Mocking APIs is an increasingly popular trend, with more and more developers seeing the advantages of mocking dependencies rather than spinning up actual duplicates of resources. On a high-level, a mock API means that you have a service that returns static data, which in turn is based on a real API.
When teams start implementing mock APIs in their development, they usually see big improvements in many areas. They no longer need to rely on development resources to be up and running, as they can just spin up their own mocks. This is a great aid in making developers more independent in their work, as they don’t have to rely on anyone else managing a development or staging environment. Financial departments are also a big fan of this approach as it can help greatly reduce cost, since you don’t need to have a complete staging environment. Many teams do opt for a staging environment, but the need for it is greatly decreased.
In this article you’ll learn about what a mock API actually is, and when you should think about using them. You’ll be introduced to many different scenarios where mock APIs are incredibly useful. Hopefully by the end of the article, you’ll have a better understanding of what it means to use a mock API.
What is a Mocked API?
A mock API is an API that responds data just like you would expect a real API to do, however it only focuses on replicating the data returned, not the inner logic that’s used to calculate the data. This is extremely useful in many cases, like when you’re using a third-party API that is rate-limited. Or, when the API you rely on isn’t fully developed yet.
For example, if you’re using Stripe to process payments for your webshop, many engineers would utilize the sandbox API that Stripe provides for testing. This is a great way to test that everything is working as expected. It might not be the production API, but being that it’s a sandbox created by the official API provider, you can assume that it’s going to behave just like it would in production.
When you’re trying to figure out how the third-party API works and how you need to form your requests, this approach is necessary. However, further down in the development process where you’re sure how Stripe returns data, you just need to make sure that your application handles the response properly. This is where mocks come into play.
To create a mocked service, you make a carbon copy of what the Stripe API (or any other API) returns. Then, you create a new service that simply responds with the same data on any given endpoint. The mock has no logic at all, and doesn’t call any external services like databases. It only returns static data.
Mock APIs in Testing
In testing methodologies, you generally define services as being in-scope or out-of-scope. The services that are in-scope are the ones you actually care about getting tested. This can be a single service or a cluster of services. Services that are out-of-scope are the ones you don’t want to test anything on, however they may end up being included in your tests because they’re a dependency of an in-scope service.
You most often see mock APIs used when you are testing a service or a cluster of services, that have dependencies that are out-of-scope. If your in-scope service calls an out-of-scope service, and the out-of-scope service suddenly starts failing, your entire test fails. This is why it’s extremely useful to use mock APIs when testing, as you can be absolutely sure that any out-of-scope services won’t be the reason your test is failing. As long as you’re using a proper mocking framework, your mocks will always behave just as you expect them to.
Main Advantages of Using Simulated Service Endpoints
There are many reasons why you would want to use mock APIs, and there are many different areas of a developer workflow where they can be useful. They can be useful at the very beginning of your software projects, during ongoing development, and even after your applications have been deployed in production. Here are some specific scenarios where you can utilize mock APIs.
While looking at these reasons, remember to think about and understand the core reason why mock APIs enable these use-cases. This way, you may be able to come up with new use-cases for yourself.
Initial Development of APIs
During the initial development of your APIs you may be lucky enough that all of your dependencies are third-party services, in which case a mock API can still be useful. However, mock APIs are an incredibly strong tool in the cases where you are multiple teams making APIs that depend on each other in some way.
Imagine you’ve just worked out the entire infrastructure plan for a new webshop. Team A starts working on the backend for the webshop, while team B is working on the frontend. Team B can start working on the design of the header, footer, and other static things. However, how are they going to design the product page? Team A has only just started working on the backend API, so they can’t use the actual backend to get the products. Well, as part of the infrastructure planning you should’ve made a specification document for the backend API. This means you know exactly what the data from the backend is going to look like, once the API is done. Team B just needs to make sure that the frontend can handle the data.
This is an opportune moment to create a mock API that can return a list of products. Now, you don’t have to wait for Team A to get the backend finished, you can start working on the entire frontend immediately.
When you’re working on an application you want to make sure that everything works as intended, even if your dependencies aren’t working as expected. It’s very common that you’ll be able to use a sandbox API to test your third-party APIs, which will return perfect example data. But, do you know how your application will react when you suddenly get a product name that’s five times the length of normal product names? Does the name overflow to a new line? Does it go outside the box? You don’t really have any way of knowing. With a mock API, you can return exactly the data you want to return.
If you want to have a product name with 255 characters, you can simply configure your mock to return that. Maybe you want to see how your application handles the
Content-Type header not being present or being different, you can just change it in your mock. Using a mock API lets you simulate your responses to fit the exact need you have.
Testing All Possible Branches
Like the previous point of how simulating responses can let you see how your application responds to various response modifications, changes to your mock API will also let you test all the different branches of your code. Having an application that doesn’t include at least a few
if-statements is fairly rare, as you (should) always have some form of error handling at least. You may be lucky enough that the sandbox API you have access to, also allows you to make requests that intentionally result in errors. However, you’re limited to the responses that the API provider has created.
With a mock API, you can define exactly the errors you are handling in your application. Most of the time in a frontend application you will have generic error-handling, without too much of a distinction between different errors. But, in a backend application you are likely to have more specific error handling depending on the type of the error. For example, some errors may require a few retries, while others are more serious and mean you need to restart the application. With a mock API, you’re able to replicate all error scenarios and test all branches of your code.
While not unique to mock APIs, and while you definitely don’t need mock APIs in order to do load testing, it can certainly be a big help. Say that you have an application that you want to hit with 50.000 requests, which isn’t unusual. The Service-under-Test may have three dependencies that need to be hit for every request. Suddenly you’re not only load testing your own service, you’re also load testing the dependencies. The resources required for such a load test can also be expensive. In some cases you want to test the resiliency of your entire infrastructure, in which case this is fine. However, when you just want to test a single service, you want to use a mock API.
Using mock APIs can also help make your load testing more reliable. Using a mock API, you know that all the service dependencies "work". You don’t risk your load testing resulting in a failure because of a failing dependency.
Mock your 3rd Party APIs
As already mentioned quite a few times throughout this article, a mock API is a great replacement for a 3rd party API. Using a mock API allows you to test your application without worrying that you’re hitting any API limits that may have been set by your API provider, which is very common especially with sandbox APIs. To make everything easy, a mock API can be used as a drop-in replacement for your third-party APIs, as long as they follow a conventional protocol like HTTP or gRPC. This will of course depend on the tool you’re using to implement your mocks.
This is useful when you’re doing local development, but it’s also incredibly useful when you’re doing stuff like CI/CD, as you can spin up your application and not have to worry about egress rules and API keys. While a sandbox API will likely require an API key, for example to do rate limiting, a mock API will always return a static response when you hit a specific endpoint, it doesn’t matter what API key you are sending. So for scenarios like this, using mock APIs make testing a lot easier.
Sometimes you know that everything works as expected, you’ve tested all the paths of your code, and everything seems fine. However, as most engineers know, nothing is ever perfect. Sometimes bits will flip or another service may just behave unexpectedly. In general, scenarios will happen that you haven’t expected. Mock APIs are also great for simulating chaos.
Again, with mock APIs you can configure the exact responses you want, however many tools that help you with mock APIs also have an option for introducing chaos. This can be chaos like not returning a response, returning a bad status code, or increasing the response time. This will let you see how your application handles unexpected errors.
An increasingly common methodology in testing, is contract testing. With contract testing, you record the interaction between two services and store it in a contract. Then, when you make changes to your application, you need to validate that your application is still upholding that contract. A contract can be something like returning data in a specific schema when a request to your API is made.
When you need to test that your frontend is able to handle the data that it receives from the backend, in contract testing you don’t actually use the backend. Instead, you pull the contract from a contract store, and then create a mock API based on this. A great tool will be able to help you get this deployed automatically, meaning you can just run your tests with a simple command.
By now, you have a greater understanding of how mock APIs work, and you can see why the concept has gained more and more traction over the years. Mock APIs can in general be a great help in being a drop-in replacement for third-party APIs, which unlocks many useful use-cases. From the beginning of developing your application, to load testing it before deploying it, to testing new branches of your code after it’s deployed. You should now understand that in many cases, using mock APIs can be a great addition to any development workflow, and speed up development considerably.
If this has made you want to implement mock APIs in your own workflow, you need a tool to do so. Check out Speedscale, a tool that focuses on helping you implement mock APIs quickly in your Kubernetes infrastructure, leveraging recorded traffic to auto-generate them.