One of the most significant difficulties when coding unit and integration tests is to isolate the component being tested and mimic the external system's behavior. Stub and verify methods help address this issue.
Knowing how to use stubs and verification correctly can make your tests stronger, targeted, and more maintainable. In this blog, we'll demystify what "stub and verify" is, when to apply it, and how it fits into a contemporary testing process.
What Is a Stub?
A stub is a snippet of code that stands in for an actual component or service in your application during testing. It returns pre-programmed responses to method calls or requests made by a test, so you can control the environment independently of external systems such as databases, APIs, or file systems.
For instance, if your method retrieves information from some external API, you can make the API call stubbed so that it returns a certain response—whether the external service is online or offline or not.
Use Cases for Stubs:
- Substituting slow or untrustworthy pieces of hardware during tests
- Mocking out error situations or edge cases
- Having the ability to dictate the data coming back from external systems
- Getting tests to execute more deterministically and quickly
What Does Verify Mean in Testing?
Verification is the act of checking that certain interactions took place when the test ran. That is, you verify if a method was invoked, how many times it was invoked, and with what arguments.
Verification assists in answering questions such as:
- Did the function invoke the logger after finishing an operation?
- Was the email service invoked with the appropriate parameters?
- Did the method touch a database while running?
It's particularly helpful in behavioral unit testing, where you're concerned not only with the result of a function, but with how it cooperates with other aspects of the system.
Stub and Verify: Together at Last
Combining stub and verify enables you to both fake the environment and assert proper behavior.
Let's go through a simple example in a Node.js environment with Jest:
```javascript
// paymentService.js
function processPayment(user, amount, notifyUser) {
if (amount > 0) {
// Process payment logic.
notifyUser(user, "Payment successful");
}
}
```
Now, in the test:
```javascript
test('should notify user after successful payment', () => {
const mockNotify = jest.fn(); // stub
processPayment("John", 100, mockNotify);
expect(mockNotify).toHaveBeenCalledWith("John", "Payment successful"); // verify
});
```
Here:
- `mockNotify` is a stub that simulates the `notifyUser` function.
- `expect(mockNotify).` is the **verification** step to ensure the function was called correctly.
Why It Matters
In real-world applications, code rarely works in isolation. Services call APIs, process events, store data, and more. Without *stub and verify* techniques, testing becomes a mess of fragile dependencies and flaky test cases.
Here’s why mastering these techniques is essential:
- ✅ Faster tests — You don't have to depend on actual databases or third-party services.
- ✅ More stable tests — Get a hold of dependency behavior.
- ✅ Behavior-driven validation — Check that the appropriate interactions took place.
- ✅ Better test coverage— It is easy to deal with error conditions and edge cases.
Tools That Support Stub and Verify
Based on your programming language, there exist numerous libraries available that support both stubbing as well as verifying:
- JavaScript: Jest, Sinon.js
- Java: Mockito
- Python: unittest.mock, pytest-mock
- Go: GoMock
- C#: Moq
These frequently provide support for both stubbing behavior and verify calls in straightforward and expressive way.
Using Keploy for Stub and Verify
Keploy provides a new, AI-driven method of test generation, such as automatic stubbing (mocking) and behavior checking. Through the recording of actual API traffic and system interactions, Keploy is able to:
- Stub dependencies such as databases and third-party APIs
- Create test cases with actual data and interactions
- Replay tests deterministically for verification
- Minimize boilerplate in test environment setup
This makes Keploy particularly effective for microservices and big systems where manual stubbing is time-consuming and error-prone.
Final Thoughts
The stub and verify combination is a building block of contemporary software testing. It enables you to write concise, targeted, and trustworthy tests by emulating the world around your code and verifying that it acts as expected.
Whether you are writing unit tests for an individual function or integration tests for a bigger system, learning and implementing stub-and-verify methods will speed up your test suite, make it more deterministic, and easier to keep in sync.
Ready to automate stubbing and verification? Check out tools like [Keploy](https://keploy.io/) to streamline and scale your test process.