How to mock fetch calls with jest
Learn how you can mock fetch calls in unit tests with jest and no other library
When you write unit tests, you don’t want to make the actual api calls to the server every time you run them. There are a few reasons for that:
- It’s a unit test, not an integration one.
- The api owners, even if it’s you, may not appreciate you hitting the api every time the ci runs.
- You can not test for every possible api response.
- You can not test for api failures.
- Much slower tests.
- and so on…
Check out the following code
We have a function calling an api to get the price of gold for the past days. The api returns the price for each day as an array. Once we get the prices, we add them up and return the average with two decimal places.
Now, let’s test this
Make sure jest is installed
The test is straightforward, we call the function to get the average price for the last 7 days and we check if the value matches the expected one.
It’s quite simple, right?
There is a key detail missing here. If we do this, we would be querying the api and we can’t possibly predict what we are going to get back. Your tests might work today, but tomorrow they probably won’t.
The solution is to use jest to mock the fetch function globally. Looking at the code we are testing, we can see two promises: One for the actual call and one for the JSON response.
We have to mock both promises with jest.fn to get the same behavior:
By doing this, when the function getPricesLastDays calls fetch, the mocked out version of fetch will be called. Thus, we have a predictable return.
All together now
Other advantages of the jest mock functions
As we just saw, the mocks are called instead of the actual implementation. We can also mock errors with mockRejectedValueOnce.
The rejection happens only once, any following calls will return the default mocked response.
Other options are:
mockImplementationOnce
to mock the value only once.mockClear
to reset the calls (useful when setting up the tests).- And much more on official docs.
Mock functions also have a property called.mock
which stores data about the calls. Like how many times it was called or what arguments were passed. More about it here.
Conclusion
With jest, you have all the advantages mentioned before while making your tests more reliable and much easier to maintain. Now, I invite you to dive into the jest documentation and find out what else you can do with it.
Bonuses
- For more robust mocks, there is a package called jest-fetch-mock.
- To mock requests on the network level, there is the Mock Service worker.