If you have a module that talks to a remote service (e.g. a HTTP API) and your test case is dependent upon a certain response from that service, there may be occasions when the desired response cannot be feasibly achieved.
In this situation it's vital to ensure determinism, so it's time to reach for a [[Test double]] - a component that looks like the remote service, but is really just a pretend version that mimics the remote system's behavior. The double needs to be setup so that provides the right kind of response in interaction with our system, but in a way we control. In this manner we can ensure determinism.[^mf1]
Here are some examples of non-deterministic behaviour of remote services where a test double may help with testing:
- **Clock time**. The remote service only responds in the way our test requires at certain times.
- **Data seeding**. The remote service cannot be seeded with the data we need for our test case, e.g. it's too much effort or impossible to provision a dedicated service instance for testing or to seed this data into a shared system.
- **Latency**. The remote service needs to make a computationally heavy calculation in order to return the requisite data for the test and this results in an unacceptable latency.
- **Transient errors**. Remote service returns different error messages based on transient events that can't be practically recreated in the test environment (e.g. a HTTP service is overloaded with requests and returns )
[^mf1]: [Non-determinism in remote services](https://www.martinfowler.com/articles/nonDeterminism.html#RemoteServices) by [[@Martin Fowler]]