Test Stub

Beginner

A Test Stub is a simple, simulated object used in testing to stand in for a real dependency. It provides predefined, hard-coded answers to method calls, allowing the component under test to be tested in isolation under controlled conditions.

First used·1970s

Definitions·1

Synonyms·1

Category·Software Testing

Also known as

Stub

Definitions

What it means.

  1. 01

    Test Stub in Software Testing

    A Test Stub is a controllable replacement for an existing dependency (or collaborator) in the system. The stub has the same API as the dependency, but the implementation is simplified. It's designed to return specific, hard-coded values or responses to the system under test (SUT).

    Stubs are a type of Test Double, a general term for any object that stands in for a real object during a test. The primary purpose of a stub is to provide the SUT with the necessary data or state to execute a specific test case, thereby isolating the SUT from its actual dependencies.

    Key Concepts

    • State Verification: Stubs are primarily used for state verification. This means you use a stub to provide input to the SUT, and then you check the final state of the SUT to see if it behaved correctly. The stub itself is not verified; it's just a means to an end.
    • Isolation: By replacing a real dependency (like a database, a web service, or a complex component), a stub allows you to test a single unit of code in isolation. This makes tests faster, more reliable, and easier to write and debug.
    • Canned Responses: A stub's core feature is providing "canned" or predefined answers. For example, a stub for a user repository might be configured to always return a user object with the name "John Doe" whenever its getUser method is called.

    Example (Pseudocode)

    Imagine you are testing a DiscountCalculator that depends on a ProductService to get a product's price.

    // The dependency we want to replace
    interface ProductService {
      Price getPrice(productId);
    }
    
    // The system under test (SUT)
    class DiscountCalculator {
      ProductService service;
      Price calculate(productId) {
        Price originalPrice = service.getPrice(productId);
        // Apply a 10% discount
        return originalPrice * 0.90;
      }
    }
    
    // The test using a stub
    test "should apply 10% discount" {
      // 1. Create the stub with a canned response
      stub ProductServiceStub implements ProductService {
        Price getPrice(productId) {
          return 100.00; // Always return 100.00
        }
      }
    
      // 2. Inject the stub into the SUT
      DiscountCalculator calculator = new DiscountCalculator(new ProductServiceStub());
    
      // 3. Call the method and assert the result
      Price finalPrice = calculator.calculate("some-product");
      assert(finalPrice == 90.00);
    }
    

    In this example, the ProductServiceStub allows us to test the DiscountCalculator's logic without needing a real ProductService, which might involve slow network or database calls.

Origin

Where it comes from.

Etymology

The term "stub" in programming originates from the concept of a placeholder, analogous to a ticket stub or a check stub, which is a smaller part representing a whole. In software, it's a minimal implementation of an interface or function, just enough to allow the calling code to link and execute without the full implementation being present.

Historical context

The concept of stubs has its roots in the top-down design and modular programming methodologies of the 1970s. In this approach, developers would write high-level modules first and use stubs as placeholders for the lower-level modules that were yet to be implemented. This allowed them to test the overall program flow and logic before all the individual components were complete.

The use of stubs for automated unit testing became much more prominent with the rise of agile methodologies like Extreme Programming (XP) and frameworks like JUnit in the late 1990s and early 2000s. These practices emphasized testing code units in isolation.

The terminology around test doubles, including the specific distinction between stubs, mocks, fakes, and spies, was significantly clarified and popularized by Gerard Meszaros in his influential 2007 book, "xUnit Test Patterns: Refactoring Test Code."

Usage

In context.

  • To verify the error handling path, we configured the Test Stub to throw a 'ServiceUnavailable' exception when its connect method was called.

  • Our unit tests run quickly because we use a stub for the external API, which returns a canned JSON response in milliseconds.

  • The developer injected a Test Stub for the user repository to ensure the isAdmin check always returned true for the test case.

FAQ

Common questions.

The primary difference lies in what is being verified. A Test Stub is used for state verification. It provides predefined data to the System Under Test (SUT), and you then assert that the SUT's final state or return value is correct. The stub itself is not inspected.

A Mock Object is used for behavior verification. It is programmed with expectations about which of its methods will be called, how many times, and with what arguments. The test fails if the SUT does not interact with the mock in the expected way. In short: stubs provide state, while mocks verify interactions.

Taxonomy

Filed under.

Categories

Software TestingSoftware Development

Tags

TestingUnit TestingTest DoubleIsolationTDD