Advanced testing in React Native with Jest: Mocking

This post is part of my series on unit testing with Jest in React Native. You can find the introduction here.

While unit testing your code with Jest, you may come across a time when you have to emulate a certain function. For example, the fetch function that performs HTTP requests, or some hardware-related routines. In such cases, you have to use mocking. Thankfully, jest supports various mocking styles out of the box.

Mocking 101

To mock a module simply means to simulate its behavior. This is required when the routine you are testing has complex external dependencies which would be hard to incorporate in a unit test. The way jest handles mocking is through a mock function. A mock function is created like this: jest.fn(). You can then specify the implementation of this function, its return value and perform assertions on it. Check out this example:

You can read more about mock functions in jest docs.

Automocking

The simplest way to use mocking is to enable Jest automocking feature. With this setting, Jest will mock all modules used by your code. In this case, you will have to manually unmock the module you are about to test, leaving everything else mocked. This is the easiest way and saves you time by not defining mocks for every function you are about to call. You can enable automocking by adding this line to your Jest config:

automock: true

That’s it! Now, all the code is mocked. To unmock a specific module you are about to test, use

jest.unmock(module name);

This approach has a few downsides, though. It can break some test cases if they were written without automocking in mind. Also, you might not want to mock that many modules and unmocking will take too much effort. Automocking generally works well for big projects without existing tests as a way to easily introduce them.

jest.mock

Another approach is to mock a specific module. To do it, use jest.mock(module name). You can optionally provide a function to customize the mocking result. Check out this example:

You can see that we mock the axios module and our redux state. For axios, the default mocking is used, while for redux we specify a custom implementation.

jest.spyOn

Sometimes, you want to keep the behaviour of a function, but still assert when and how it was called. For these purposes, jest.spyOn is the way to go.

You can see that we are spying on the console.error function to make sure do_stuff does not log anything to the console. It does, though, and the test fails. Please note that the original console.error is still called in this case, unlike previous examples.

Now you should have a better understanding of mocking modules while testing. In the next parts, I will cover coverage reports and component testing.

Get new content delivered to your mailbox:

leave a comment