I am developing a web app along with a backend API. The backend however must talk to other services, some of which are internal and others are not.
In an ideal scenario we would spend time and have a local copy of all services running, but this is not possible due to; some services being 3rd party and other internal services are not accessible for all team members.
I would therefore like to know how best to handle this when we cannot have a copy running locally, and interacting with the actual hosted services is not a good idea due to data sync issues.
I would really like to avoid peppering the codebase with
if(local) executeMockCall(); but I am not clear what other options there are.
Invert your dependencies: make the external service into a plugin to your application. Then, attach different implementations depending on whether you're running in a production environment or a development environment.
First, define an interface through which your application communicates with the third party service. With interface I mean anything from a bunch of functions in your code to a REST API, the important point is just that you can select an implementation of this interface at run time. For example, you could provide an environment variable that contains an URL that points to a microservice that provides the expected interface. Or, you could have an if/else at the beginning of your program that selects one of two classes.
Then, create two implementations of your interface:
The real implementation that translates your operations to the third party service.
The testing implementation that produces dummy results.
The point is that instead of choosing the real or mock implementation throughout your code, that your main code remains agnostic to which implementation it is talking with. This is more testable, and also much less error-prone. The decision to use a particular implementation is made once, and preferably outside of the app. Instead, the choice should be made by the environment in which the app is being run.
External links referenced by this document: