Test Stub
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
Definitions
What it means.
- 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
getUsermethod is called.
Example (Pseudocode)
Imagine you are testing a
DiscountCalculatorthat depends on aProductServiceto 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
ProductServiceStuballows us to test theDiscountCalculator's logic without needing a realProductService, 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
connectmethod 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
isAdmincheck 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
Tags