I’ve been working with Jest and Enzyme to test React Native apps recently and one of the biggest challenges was testing asynchronous methods of my React Native components. I will go through how to test an asynchronous methods including what I found to be the most challenging part: mocking the fetch API. Here is the example project that I will use below.
As I observed in a recent article, the tools and logic used to test a React app can easily re-used with React Native — you just have to take care when setting up the infrastructure.
Bearing that in mind, this article will refer to ‘React Native’ but the approach used below can be used to test asynchronous methods of React components, too.
The biggest challenge I found was finding the right way of mocking the fetch API inside of the test.
In this article I am going to go through the approach I took to mock the fetch API to explicitly test asynchronous methods using Jest and Enzyme.
First, why the need for explicit testing?
You can implicitly test a method using Enzyme to ‘find’ an element inside of a snapshot and simulate an event like a click and then test the result of this action. But this is only useful if you are testing a method that is bound to an element of the DOM such as a button.
So, there is a need for explicitly testing component methods.
Invoking a component method
Enzyme provides a really simple way of calling a particular method of a component inside a unit test.
You can use the shallow API provided by Enzyme to render a component (it is ‘shallow’ rendering as it does not render any children of the component).
Then use the ‘instance’ method of the wrapper object to create a local instance of the (shallow) component to use within the test.
This provides a neat way of testing component methods explicitly inside of unit tests.
Testing an async method
The getPersonData method in the example method below uses the fetch API to get data from a server using the SWAPI.
We need to take some measures to mock the fetch API inside of our tests to simulate the response from the server.
Why the need to mock?
Firstly, it is always important to be clear on what what we actually want to test. Here we are testing whether a method returns a piece of data after a HTTP request has been made. We are using a tool to make the request for us (the fetch API that is provided by the hosting environment) and so, importantly, we are not testing the fetch API. This (should be) is the responsibility of the API authors.
Secondly, making a request to a remote web server could take an unknown amount of time and it can make our tests more fragile because tests may fail if there is something wrong with the server. So we need to mock the functionality of the fetch function.
There are several approaches to doing this but the one that worked the best for me and what I believe is cleanest approach is using the fetch-mock library.
You can think of the use of the fetchMock function below as saying to the test: “inside of this test, whenever the fetch API is called with this particular URL, don’t actually make the request but always return this mockResponse immediately”
Note: since this approach mocks all calls to the fetch API within the test I have avoided the complication of using dependency injection and treating fetch as a parameter within the method. I believe that by avoiding this the testing code is clearer.
I went through how to test asynchronous methods of a React or React Native component using Jest and Enzyme. The important point to take away was how to mock the fetch API with fetch-mock .
I hope you found this useful. Please post any comments or questions below!