My previous article on unit testing React components with Jest + Enzyme, was a guide to understand the basic concepts required when writing unit tests with Jest and Enzyme for a project scaffolded with create-react-app. In this article, we will build on that.
Components that make API calls rely on external modules when handling a request. Such dependency comes with it some pitfalls, for example, our test would fail if changes are made to the external module our component depends on, such as changing an API key.
However, to successfully test the component, is to isolate the component from its external dependencies. To achieve this, we have to mock the module our component depends on, with Jest.mock().
Read this article on Jest.mock() the author did a great job 👏 😃
The goal of mocking is to replace something we don’t control, with something we do. With jest.mock(), we automatically set all exports of a module to a mock function. — ‘Rick Hanlon II’
Let’s start testing:
Here is the file structure of the component that is being tested.
Here is the component that is being tested.
In the component, we used componentDidMount, a react lifecycle method to invoke an API call, to load the data that would be rendered by the component.
To write a test for this component, there are terms I would like to highlight:
To test a react component that calls a react life-cycle method, we would use Enzyme’s mount method instead of the shallow method, to render the component we are testing.
Jest.spyOn keeps track of invocations made on the module function. With that, we can make assertions on them to know if the function they are tracking is called.
Here is the test file…
For the first specification on the test file, we have used jest.spyOn, to track the invocation of the search function.
When you mock a module, there is property the function can access — mock which inspects the mock state.
Line 19 returns an array whose containing elements are the arguments passed into search method while calling it from itemList.jsx
In lines 22, we accessed the function that is passed to the search method in itemList.jsx.
In line 23, ids, a fake data, which represents the response we should get from a real API call, was passed into the function.
An assertion is made on lines 24 and 25. It is expected that client.search() would be called and the component’s state updated with the fake data-(ids).
Here is the file we mocked.
To test components that make API calls, it is important to understand how to mock modules. With Enzyme’s mount() method and jest’s spyOn() method interacting and making assertions on expectations is much easier.