Labs ICT
Pro Login

jest.spyOn()

Watching how functions are called.

jest.spyOn()

Mocking an entire module is sometimes overkill. What if you just want to watch one method on an object and maybe change its behavior? That is where jest.spyOn comes in.

Think of spyOn like putting a wiretap on a method. You listen to what it does, and you can optionally intercept and change its behavior.

Basic Spy

You give spyOn an object and a method name. It wraps that method so you can track calls to it.


const calculator = {
  add: (a, b) => a + b
};

const spy = jest.spyOn(calculator, 'add');

calculator.add(2, 3);

expect(spy).toHaveBeenCalledTimes(1);
expect(spy).toHaveBeenCalledWith(2, 3);

spy.mockRestore();
    

After you spy on it, every call to calculator.add goes through your spy first. Always restore your spy when you are done so it does not leak into other tests.

Changing Behavior with mockImplementation

You can replace the original method behavior with your own implementation.


const user = {
  getName: () => 'Alice'
};

const spy = jest.spyOn(user, 'getName')
  .mockImplementation(() => 'Bob');

expect(user.getName()).toBe('Bob');
expect(spy).toHaveBeenCalled();

spy.mockRestore();
    

Spying on Console Methods

A common use case is testing console.log calls. You spy on console.log, check if it was called, then restore it.


it('logs a message', () => {
  const spy = jest.spyOn(console, 'log')
    .mockImplementation(() => {});

  console.log('hello');

  expect(spy).toHaveBeenCalledWith('hello');
  spy.mockRestore();
});
    

Auto-Restore with spyOn

If you use jest.spyOn and the original method is not configurable, Jest auto-restores it. But to be safe, always call mockRestore in an afterEach hook.


let spy;

afterEach(() => {
  if (spy) spy.mockRestore();
});

it('spies on method', () => {
  spy = jest.spyOn(console, 'log').mockImplementation(() => {});
  console.log('test');
  expect(spy).toHaveBeenCalled();
});
    
Try it Yourself →

Key Takeaways

  • jest.spyOn watches a method without replacing the entire module
  • Use mockImplementation to change what the spied method does
  • Always call mockRestore when you are done spying
  • Spies are great for checking side effects like console.log
  • Use afterEach to auto-restore spies and avoid test contamination