Copy-ready Jest patterns

Jest SpyOn examples for real tests

Find the testing goal you need, understand why the pattern works, and copy a clean jest.spyOn() example without digging through unrelated documentation.

example.test.js Copy-ready
const spy = jest
  .spyOn(api, 'getUser')
  .mockResolvedValue({
    id: 1,
    name: 'Alex'
  });

await api.getUser();

expect(spy)
  .toHaveBeenCalledTimes(1);

What are you trying to test?

Choose your testing goal and jump directly to the smallest useful Jest SpyOn example.

Copy the pattern that matches your test

Each example starts with the testing intent, shows the minimum useful code and explains what the assertion proves.

Basic jest.spyOn() example

Start here when the real method already exists and you only need to check whether your application called it.

Use this when

You want to watch an existing method without changing what that method does.

Basic spy
const user = {
  getName() {
    return 'Alex';
  }
};

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

user.getName();

expect(spy).toHaveBeenCalledTimes(1);
What this proves

Jest confirms that user.getName() was called once. The original function still runs.

Check arguments with toHaveBeenCalledWith()

Use this pattern when the important question is not only whether the function ran, but exactly what data your application passed to it.

Use this when

You need to verify a string, object, ID, options object or another value passed into a method.

Check call arguments
const api = {
  send(message) {
    return message;
  }
};

const spy = jest.spyOn(api, 'send');

api.send('hello');

expect(spy)
  .toHaveBeenCalledWith('hello');
What this proves

The method was called with exactly 'hello'.

Mock a return value

Use mockReturnValue() when the method is synchronous and your test needs a predictable result instead of the real value.

Use this when

The real implementation is unpredictable, expensive or irrelevant to the behavior you are currently testing.

mockReturnValue()
const userService = {
  getName() {
    return 'Real User';
  }
};

const spy = jest
  .spyOn(userService, 'getName')
  .mockReturnValue('Test User');

expect(userService.getName())
  .toBe('Test User');

expect(spy)
  .toHaveBeenCalledTimes(1);
Important: after you add mockReturnValue(), the real implementation does not run for that mocked call.

Replace behavior with mockImplementation()

Use mockImplementation() when one fixed return value is not enough and the mock needs its own logic.

Use this when

Your fake method needs to inspect parameters, calculate a value or behave differently for different inputs.

Custom implementation
const math = {
  multiply(a, b) {
    return a * b;
  }
};

const spy = jest
  .spyOn(math, 'multiply')
  .mockImplementation((a, b) => {
    return a + b;
  });

expect(math.multiply(4, 5))
  .toBe(9);

expect(spy)
  .toHaveBeenCalledWith(4, 5);
Why this works

The spy still records every call while your test controls exactly what the method does.

Mock async success with mockResolvedValue()

Use this pattern when the real method returns a Promise and your test needs a successful response without making a real request.

Use this when

You are testing API, database or other Promise-based application behavior.

Async resolved value
const api = {
  async getUser() {
    return fetch('/user');
  }
};

const spy = jest
  .spyOn(api, 'getUser')
  .mockResolvedValue({
    id: 1,
    name: 'Alex'
  });

await expect(api.getUser())
  .resolves
  .toEqual({
    id: 1,
    name: 'Alex'
  });

expect(spy)
  .toHaveBeenCalledTimes(1);
What this avoids

Your unit test does not need a real network request to receive a predictable result.

Mock async failure with mockRejectedValue()

Use this when you need to verify what your application does after an API request, database call or another Promise rejects.

Use this when

You need to test error handling, retries, fallback messages or failed requests.

Async rejected value
const spy = jest
  .spyOn(api, 'getUser')
  .mockRejectedValue(
    new Error('Request failed')
  );

await expect(api.getUser())
  .rejects
  .toThrow('Request failed');

expect(spy)
  .toHaveBeenCalledTimes(1);
This pattern lets you test failure behavior without forcing a real external service to fail.

Spy on a class method

Instance methods usually live on the class prototype. Spy on the prototype before your application creates or uses the instance.

Use this when

Your method belongs to instances created from a class rather than a plain object.

Class prototype
class UserService {
  getName() {
    return 'Alex';
  }
}

const spy = jest.spyOn(
  UserService.prototype,
  'getName'
);

const service = new UserService();

service.getName();

expect(spy)
  .toHaveBeenCalledTimes(1);
Target matters

The method lives on UserService.prototype, so that is the object Jest needs to watch.

Spy on a getter

Getter and setter properties are not ordinary callable methods. Pass a third argument to tell Jest which accessor you want to spy on.

Use this when

The property is accessed with a getter or setter rather than called like a function.

Getter spy
const user = {
  firstName: 'Alex',

  get displayName() {
    return this.firstName;
  }
};

const spy = jest.spyOn(
  user,
  'displayName',
  'get'
);

const name = user.displayName;

expect(name).toBe('Alex');

expect(spy)
  .toHaveBeenCalledTimes(1);
For a setter, use 'set' instead of 'get' as the third argument.

Restore the original method with mockRestore()

Restore a spy after changing its implementation so mocked behavior does not leak into another test.

Use this when

You temporarily replaced the real method and need the original implementation again.

Restore original behavior
const service = {
  getValue() {
    return 'real';
  }
};

const spy = jest
  .spyOn(service, 'getValue')
  .mockReturnValue('mocked');

expect(service.getValue())
  .toBe('mocked');

spy.mockRestore();

expect(service.getValue())
  .toBe('real');
After mockRestore()

Jest removes the temporary spy behavior and restores the original method.

Common questions about Jest SpyOn examples

Quick answers for choosing the right spy pattern for your test.

Create the spy using jest.spyOn(object, 'method'), call the method and assert the call with a matcher such as toHaveBeenCalledTimes().

Chain mockReturnValue() after jest.spyOn() for synchronous values. For successful Promises, use mockResolvedValue().

For a normal instance method, spy on ClassName.prototype. Static methods should be spied on directly from the class.

Restore the spy when you changed its implementation and want to make sure temporary mocked behavior does not affect another test.