Jest mock and spy — mockClear vs mockReset vs mockRestore
When to use mockClear, mockReset and mockRestore with mock and spyOn.
When writing unit tests we need to make sure that every test is independent of others. When using shared mocks/spies we need to remember that they should have initial values and states for each test.
We cannot allow that one test will use the mock and that mock will be used in another test. That can lead to situation when test are passing but only in specific order. When we will be updating one tests all other might start failing. If something like this is happening we most probably don’t have mocks properly cleaned up.
The most common mistake I saw many times is usage of jest.resetAllMocks
when we should actually use jest.clearAllMocks
and other way around.
But there is also third method — the restore
method.
Let’s try a simple module with one function:
We will be cleaning up only this one mock/spy so we will use methods: mockClear
, mockReset
and mockRestore
.
We need also to remember that the mockReset
and mockRestore
methods works a little bit differently for mocks and spies. Let’s take a look at separate examples with spy and mock.
SPY
In this example we are using spyOn
to hook to the whoAreYou
function and replace (mock) the implementation with our own.
The output will be as follows:
The clear
and reset
methods cleans the internal state of the mock so our expect
on how many times the mock was called are always 1
.
The difference between those two is that the reset
destroys also our mock implementation and replaces it with function with no return value. That is why in output we have undefined
.
The restore
method however removes the mocked implementation and replaces it with original method. Because the mock was not called we expect
that the mock will be called 0
times.
MOCK
Here we are mocking whole module and mock the whoAreYou
function. We also introduce new implementation for that function.
The output is slightly different than in previous example:
In this case all methods cleans the internal state of the mock and we expect
them to be called 1
time. In this case mockRestore
does not restore original implementation — it just restores the mock to original value: jest.fn()
.
BONUS: How to restore the mock
As we can see in above example, the mockRestore
method does not give us the original implementation like in case of spy.
To do that we need to mock implementation with the original implementation (no matter how weird it may sound).
And we got the original implementation. The only difference is that the original implementation is inside the mock. So we have the second expect
with called times equal to 2
. In case of spies the spy internal state did not change as the original function was called.
Conclusion
We usually use both — mocks and spies in same tests suites. So we need to remember the differences of those methods, not just blindly clear
, reset
or restore
.
Our tests should not make side effects for other test.
Use the clear
method when sufficient and be careful with the reset
method.
It is pretty easy to remember which method is the most destructive. Just use the alphabetical order of those methods: clear
, reset
, restore
. The first one is the less destructive and the last one the most.
Article repository: https://github.com/marekrozmus/blog-mock-spy-clear-reset-restore
Check also my other posts about unit testing: