Apparently mock.mockRestore() does not restore the original implementation of a mock created using jest.mock()
// a.js
export default class A {}
// b.js
import A from './a';
export default class B extends A {}
// test.js
import A from './a';
import B from './b';
jest.mock('./a');
jest.mock('./b');
const b = new B();
test('instanceOf', () => {
A.mockRestore();
B.mockRestore();
expect(b).toBeInstanceOf(A); // fails
});
mockClear() does, and also removes any mocked return values or implementations. This is useful when you want to completely reset a mock back to its initial state. (Note that resetting a spy will result in a function with no return value).
Mock functions allow you to test the links between code by erasing the actual implementation of a function, capturing calls to the function (and the parameters passed in those calls), capturing instances of constructor functions when instantiated with new , and allowing test-time configuration of return values.
To spy on an exported function in jest, you need to import all named exports and provide that object to the jest. spyOn function. That would look like this: import * as moduleApi from '@module/api'; // Somewhere in your test case or test suite jest.
mockFn.mockRestore
only works for a mock function created with jest.spyOn
:
const obj = {
func: () => 'original'
}
test('func', () => {
const mock = jest.spyOn(obj, 'func');
mock.mockReturnValue('mocked');
expect(obj.func()).toBe('mocked'); // Success!
mock.mockRestore();
expect(obj.func()).toBe('original'); // Success!
})
jest.spyOn
wraps the original function and provides mockRestore
as a way to restore the original function.
jest.mock
calls work a little differently.
Jest
takes over the require
system and jest.mock
tells Jest
that it should return the module mock instead of the actual module whenever it is required.
This means that the module mock doesn't wrap the original module, it completely replaces the original module in the require
system. So mockRestore
may be defined on mock functions within the module mock, but calling it doesn't restore the original implementation.
jest.mock
is typically used when you want to mock an entire module for the whole test.
It is particularly useful when using ES6-style import
statements since babel-jest
hoists jest.mock
calls and they run before anything else in the test file (including any import
statements):
import A from './a'; // <= A is already mocked...
jest.mock('./a'); // <= ...because this runs first
test('A', () => {
// ...
}
There isn't an easy way to restore the original module during a test that uses jest.mock
since its primary use is to mock a module for an entire test.
If you are trying to use both a mock and the original implementation during the same test there are a few options:
jest.spyOn
and restore it using mockRestore
jest.doMock
to avoid the hoisting behavior of jest.mock
...just note you also need to use require
within the scope that uses jest.doMock
instead of using a top-level import
jest.requireActual
at any time to require
the original moduleIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With