Use jest.spyOn()
- The method already exists on an object.
- You want to track calls to the real method.
- You may want the original implementation to run.
- You may temporarily mock the method and restore it.
Both can track calls and control mock behavior, but they start from different situations. Compare them side by side and choose the right Jest mock for your test.
jest.spyOn()
Watches a method that already exists and calls the original implementation by default.
jest.fn()
Creates a new mock function with no original implementation unless you provide one.
Use jest.spyOn() when the method already exists
and you want Jest to observe or temporarily change that real
method.
Use jest.fn() when you need to create a new mock
function, callback, dependency or placeholder yourself.
You already have an object method and want to watch what happens when your code calls it.
You need a mock function that does not need to wrap an existing method.
The easiest way to decide is to look at the function you are trying to test.
The important differences become clearer when you compare their behavior directly.
These examples perform similar assertions, but the mock is created in a different way.
const service = {
send(message) {
return message;
}
};
const spy = jest.spyOn(
service,
'send'
);
service.send('hello');
expect(spy)
.toHaveBeenCalledWith('hello');
const send = jest.fn();
send('hello');
expect(send)
.toHaveBeenCalledWith(
'hello'
);
service.send() already exists, so the spy
watches that real method rather than creating a separate
function.
No function existed yet. The test creates a new mock function and calls it directly.
Match your testing situation with the tool that fits it best.
The service method already exists and your application calls it.
You need a fake callback to pass into another function.
You want to observe an existing object's behavior.
Your code expects a function and you can supply the dependency yourself.
You want the real object method back after the test.
There is no real object method that needs to be preserved.
If the function already exists and belongs to an object,
jest.spyOn() is usually the clearer starting point.
If you need to create the function yourself, start with
jest.fn().
Quick answers to the differences developers most often need to understand.
jest.spyOn() wraps a method that already
exists. jest.fn() creates a new mock
function from scratch.
Yes. By default the original implementation runs. You can replace the behavior by adding a mock return value or mock implementation.
Usually yes. A callback often does not need an existing
object method, so creating it directly with
jest.fn() is simpler.
A standalone jest.fn() does not have an
original object method to restore. A spy can restore
the method it wrapped.
Continue with the guide, examples or troubleshooting page that matches your next step.