Mocking & Spying with Jest SpyOn
Mocking & Spying with Jest
It might not be obvious but there is a difference between jest.spyOn and jest.Mock. By default when using jest.spyOn the original function that you are spying on remains the same. Unlike when jest.Mock is used where the function is changed, usually by just returning a value that would be expected from the function when not in test.
When to use Jest.SpyOn?
- Use Jest.SpyOn when you want to keep the original function the same just want to know whether it was called.
- To override the implementation or result of the function for a specific scenario, restoring aftwards with mockRestore
When to use Jest.Mock?
- You want to completely override the function's implementation. You don't care what it is and are not bothered about restoring it
- You want to mock the result of the function
A reason to completely override the function's implementation could be to remove dependencies from other files which you may not need or want when running your test. If the tests are at unit test level then it makes sense to override the function because the file that you're originally testing should only be tested in isolation (when unit testing).
Example of Jest.SpyOn
// import package
import randomLibrary from './libraries/random';
// inside test (shortened for brevity)
jest.spyOn(randomLibrary, 'functionOrMethod');
Example of Jest.Mock
The following will mock all of randomLibrary's exports with the default jest.fn() implementation.
// import package
import randomLibrary from './libraries/random';
// inside test (shortened for brevity)
jest.mock('./libraries/random');
The following will mock all of randomLibrary's exports with the default jest.fn() implementation excluding the 'functionOrMethod' export that will have the implementation defined below
// import package
import randomLibrary from './libraries/random';
// inside test (shortened for brevity)
jest.mock('./libraries/random', () => {
functionOrMethod: jest.fn().mockReturnValue('10'),
});
Example of Jest.Mock (Mocking Default Import)
The following mocks the default export, similarly to how it is done for specific exports in the previous example. However, __esModule: true is added.
// import package
import randomLibrary from './libraries/random';
// inside test (shortened for brevity)
jest.mock('./libraries/random', () => {
__esModule: true,
default: () => true,
});