Mocking External APIs or services in .NET

Whether calling the external API costs money or mocking desired behavior to code specific business rules. Sometimes external APIs could be mocked during the development of services or APIs. I believe this is an important strategy in every developer’s toolbox.

But what do I mean by mocking external services or APIs? The strategy is to have a secondary implementation for that external dependency which returns the same response structure as the original, but one that you can control the responses to drive different paths on your app.

Implementation

More than likely you have implemented that external dependency with an interface and used DI to inject it into your service class. This is the key, DI.

We create two implementations and inject the different implementations into the DI container based on a configuration.

{
	"ExternalDependency": {
		"EnableMocks": true
	}
}

Setting the mocks to true, we insert the mock implementations into the DI container, otherwise, we insert the real implementation.

var builder = WebApplication.CreateBuilder(args);

var externalDependency = builder
	.Services
	.Configure<ExternalDependency>(
    	builder
    		.Configuration
    		.GetSection("ExternalDependency")
	);

if (externalDependency.EnableMocks)
{
    builder
    	.services
    	.AddSingleton<IExternalDependency, ExternalDependencyMock>();
}
else
{
    builder
    	.services
    	.AddSingleton<IExternalDependency, ExternalDependency>();
}

Now, to make sure mocks never make it to Production or even Dev or UAT environments, we create a configuration transformation in our CI/CD pipeline, setting that EnableMocks property to false. Ensuring this property will always be false, even if set to true when checked into the repo.

Some might argue this can be accomplished via unit tests, which is true to a certain extent. We can (and should) write tests to navigate different paths in our code and mock responses from external dependencies. However, I will give two of my use cases.

We have an OCR service that takes around 12 seconds (give or take) to send back a response. Internal complexities among scanning the check images a few times. I do not want to wait 12 seconds during development time to get a response back so I mock the response and control the data I get back. There are business rules around that response data that I can easily control with the mocked response. Also, I do not want to use my real checks for development.

Another external dependency costs money to call, even during development time, so once I mock the response to prevent calling the real thing.


If you liked this reading, share it on your social media and you can follow me on Twitter or LinkedIn.


Consider giving back by getting me a coffee (or a couple) by clicking the following button:

Spread the love

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.