Mocking third-party dependencies
Your service calls things you don’t run: a payment provider, another team’s gRPC service, a price feed. In a test you can’t make them fail on purpose, and you can’t ask them what your service sent. So tomato starts a stub in their place.
How it works
In production the service calls a dependency you don't run: Stripe. You can't make it fail on demand, and you can't ask it what your service sent.
Point. tomato starts a http-server stub and hands the service its address in the same variable. The service's code doesn't change.
Arrange. A Given step tells the stub what to answer: a success, an error, a delay, a refused connection.
Act. The scenario calls your service; your service calls the stub, which answers as told and remembers the call.
Assert. Then steps check your service's answer and what it sent the stub: the path, headers, body, metadata, messages.
Reset. Before the next scenario the stub forgets its answers and what it received. Scenarios never see each other's stubs.
Four moves, the same for every protocol:
- Point. The stub listens on a port you choose. The service gets that address in the same variable that holds the real one in production.
- Arrange. A
Givenstep tells the stub what to answer. - Assert.
Thensteps check what your service sent the stub. - Reset. Before every scenario the stub forgets everything.
Which stub
| The service calls | Stub | Point it with | Arrange | Assert |
|---|---|---|---|---|
| a REST API | http-server | {{.name.url}} | stub "POST" "/path" returns "201" | received "POST" "/path" |
| a gRPC service | grpc-server | {{.name.address}} | stub "pkg.Svc/Method" returns json: | received "pkg.Svc/Method" |
| a WebSocket feed | websocket-server | ws://localhost:<port> | on message "…" replies: | received message "…" |
Name a stub after what it stands in for.
"stripe-stub" received …reads on its own, and never gets confused with the client that calls your service,"shop-client".
Stub, not the real thing
A stub checks your side of the contract: what your service sends, and what it does with each answer. It can’t tell you the third party still answers that way. Keep a few smoke tests against its sandbox for that, and let the stub cover the cases a sandbox won’t give you on demand: the decline, the timeout, the outage.