Automatic Mocking

Calling jest.mock automatically mocks all the exports from the module being mocked unless a manual mock is specified using the __mocks__ directory.

So, this line jest.mock("./Logger") has automatically replaced the Logger constructor and all of it's methods with mock functions allowing us to test how these functions behave.

And the information related to the instances created by Logger is saved in Logger.mock.instances, so we can use this to test if the methods are being called properly.

Copyimport Person from "./Person";
import Logger from "./Logger";

jest.mock("./Logger");

describe("Person", () => {
  it("calls method1 on instantiation", () => {
    const p = new Person();
    // Logger constructor should have been called
    expect(Logger).toHaveBeenCalled();
    
    const mockLoggerInstance = Logger.mock.instances[0];
    const mockMethod1 = mockLoggerInstance.method1;
    // method1 should have also been called
    expect(mockMethod1).toHaveBeenCalled();
  });
});

Using Module Factory Parameter

You can also explicitly provide a module factory by passing in a factory function as the second argument to jest.mock. So, now the provided module factory would be used instead of Jest's automocking feature. Refer the docs for more information.

Copyimport Person from "./Person";
import Logger from "./Logger";

const mockMethod1 = jest.fn();
jest.mock("./Logger", () =>
  jest.fn().mockImplementation(() => ({
    method1: mockMethod1,
  }))
);

describe("Person", () => {
  it("calls method1 on instantiation", () => {
    const p = new Person();
    // Logger constructor should have been called
    expect(Logger).toHaveBeenCalled();
    // method1 should have also been called
    expect(mockMethod1).toHaveBeenCalled();
  });
});

Note: jest.mock() calls are hoisted, so you cannot first define a variable and then use it inside a factory function unless the variable is prefixed with mock. And because of this we can access mockMethod1 inside the factory.

Manual Mock

You can achieve a similar behavior to module factory function by creating a manual mock located at __mocks__/Logger.js. And now this mock implementation can be used across test files by simply calling jest.mock.

Copy// __mocks__/Logger.js
const mockMethod1 = jest.fn();
const mockLogger = jest.fn(() => ({
  method1: mockMethod1,
}));

Usage is similar to the module factory function but you now also have to import the mocked method in your test.

Note: You still need to use the original module path, don't include __mocks__.

Copyimport Person from "./Person";
import Logger, { mockMethod1 } from "./Logger";

jest.mock("./Logger");

describe("Person", () => {
  it("calls method1 on instantiation", () => {
    const p = new Person();
    // Logger constructor should have been called
    expect(Logger).toHaveBeenCalled();
    // method1 should have also been called
    expect(mockMethod1).toHaveBeenCalled();
  });
});
Answer from Som Shekhar Mukherjee on Stack Overflow
🌐
Jest
jestjs.io › es6 class mocks
ES6 Class Mocks · Jest
May 7, 2026 - Calling jest.mock('./sound-player') returns a useful "automatic mock" you can use to spy on calls to the class constructor and all of its methods. It replaces the ES6 class with a mock constructor, and replaces all of its methods with mock functions ...
🌐
DEV Community
dev.to › andrewchaa › mocking-es6-class-instances-with-jest-p6c
Mocking ES6 Class Instances with Jest - DEV Community
May 3, 2024 - Therefore, any mock for an ES6 class must be a function. You can mock them using Jest's mock functions. ... require('dotenv').config() import { MongoClient, ServerApiVersion } from 'mongodb' const client = new MongoClient( process.env.mongo...
🌐
Chris Boakes
chrisboakes.com › mocking-javascript-class-inner-functions-with-jest
Mocking JavaScript Class Inner Functions With Jest | Chris Boakes
import Foo from './foo'; import Bar from './bar'; const mockGreetWorld = jest.fn(); jest.mock( './bar', () => { return jest.fn().mockImplementation(() => { return { greetWorld: mockGreetWorld }; }); }); describe( 'helloWorld', () => { it ( 'should call greetWorld', () => { const foo = new Foo(); const bar = new Bar(); foo.helloWorld(); expect( bar.greetWorld ).toHaveBeenCalledTimes( 1 ); }); }); In this instance, we’ve called jest.mock with a module factory parameter.
🌐
W3Resource
w3resource.com › jest › es6-class-mocks.php
Jest - ES6 Class Mocks
July 12, 2024 - Please note that when you use arrow functions in your classes, they won't be part of the mock. The reason for this is that arrow functions are not present on the object's prototype, they are just properties holding a reference to a function. If there is no need to replace the implementation of the class, this will be the easiest option to set up. For instance: import SoundPlayer from './sound-player'; import SoundPlayerConsumer from './sound-player-consumer'; jest.mock('./sound-player'); // SoundPlayer is now a mock constructor beforeEach(() => { // will Clear all instances and calls to constr
🌐
Medium
channaly.medium.com › how-to-mock-an-any-instance-method-of-an-object-rspec-to-jest-d081d4cb1bf7
How to mock an / any instance method of an object — RSpec to Jest | by Ly Channa | Medium
April 25, 2024 - # rspec subject = described_class.new allow(subject).to receive(:method).and_return(any_value) ... subject.method · // jest typescript let subject = new describedClass() jest.spyOn(subject, "method").mockImplementation(()=>{ any_value}) ... subject.method() // you need to restore the implementation before the mock at the end jest.restoreAllMocks(); # rspec allow_any_instance_of(described_class).to receive(:call).and_return(any_value) ...
Top answer
1 of 1
5

Automatic Mocking

Calling jest.mock automatically mocks all the exports from the module being mocked unless a manual mock is specified using the __mocks__ directory.

So, this line jest.mock("./Logger") has automatically replaced the Logger constructor and all of it's methods with mock functions allowing us to test how these functions behave.

And the information related to the instances created by Logger is saved in Logger.mock.instances, so we can use this to test if the methods are being called properly.

Copyimport Person from "./Person";
import Logger from "./Logger";

jest.mock("./Logger");

describe("Person", () => {
  it("calls method1 on instantiation", () => {
    const p = new Person();
    // Logger constructor should have been called
    expect(Logger).toHaveBeenCalled();
    
    const mockLoggerInstance = Logger.mock.instances[0];
    const mockMethod1 = mockLoggerInstance.method1;
    // method1 should have also been called
    expect(mockMethod1).toHaveBeenCalled();
  });
});

Using Module Factory Parameter

You can also explicitly provide a module factory by passing in a factory function as the second argument to jest.mock. So, now the provided module factory would be used instead of Jest's automocking feature. Refer the docs for more information.

Copyimport Person from "./Person";
import Logger from "./Logger";

const mockMethod1 = jest.fn();
jest.mock("./Logger", () =>
  jest.fn().mockImplementation(() => ({
    method1: mockMethod1,
  }))
);

describe("Person", () => {
  it("calls method1 on instantiation", () => {
    const p = new Person();
    // Logger constructor should have been called
    expect(Logger).toHaveBeenCalled();
    // method1 should have also been called
    expect(mockMethod1).toHaveBeenCalled();
  });
});

Note: jest.mock() calls are hoisted, so you cannot first define a variable and then use it inside a factory function unless the variable is prefixed with mock. And because of this we can access mockMethod1 inside the factory.

Manual Mock

You can achieve a similar behavior to module factory function by creating a manual mock located at __mocks__/Logger.js. And now this mock implementation can be used across test files by simply calling jest.mock.

Copy// __mocks__/Logger.js
const mockMethod1 = jest.fn();
const mockLogger = jest.fn(() => ({
  method1: mockMethod1,
}));

Usage is similar to the module factory function but you now also have to import the mocked method in your test.

Note: You still need to use the original module path, don't include __mocks__.

Copyimport Person from "./Person";
import Logger, { mockMethod1 } from "./Logger";

jest.mock("./Logger");

describe("Person", () => {
  it("calls method1 on instantiation", () => {
    const p = new Person();
    // Logger constructor should have been called
    expect(Logger).toHaveBeenCalled();
    // method1 should have also been called
    expect(mockMethod1).toHaveBeenCalled();
  });
});
🌐
Meticulous
meticulous.ai › blog › mocking-a-javascript-class-with-jest-two-ways-to-make-it-easier
Mocking a JavaScript Class with Jest, Two Ways to Make it Easier
A guide on how to mock a JavaScript class using Jest, comparing dependency injection and mocking, along with guides on how to implement both.
🌐
DhiWise
dhiwise.com › post › how-to-effectively-use-jest-mock-class-constructor-in-your-cod
Mastering Jest Mock Class Constructor
July 2, 2024 - When testing, you may need to mock the behavior of a class constructor to ensure that your tests are not dependent on the actual implementation of the class. To mock a constructor function in Jest, you can use the jest.mock() function, passing ...
Find elsewhere
🌐
LinkedIn
linkedin.com › pulse › demystify-es6-class-mocking-jest-examples-gaurav-kumar-singh-ytvwf
Demystify ES6 class mocking in Jest (with examples) ...
March 27, 2024 - The factory function doesn't return a function rather it returns an object with the key that is same as the class export name i.e RedisClient. Hence, It will be able to import the mocked function correctly. If you want, you can try changing the module factory to return function like below · jest.mock("../db/redis", () => { return function () { return { getValue: () => "Mocked value", addValue: () => ({ status: "ok" }), }; }; });
🌐
Jest
jestjs.io › mock functions
Mock Functions · Jest
May 7, 2026 - The mocked() helper method wraps types of the source object and its deep nested members with type definitions of Jest mock function. You can pass {shallow: true} as the options argument to disable the deeply mocked behavior.
🌐
npm
npmjs.com › package › jest-create-mock-instance
jest-create-mock-instance - npm
Create class mock instances easily with Jest. Latest version: 2.0.0, last published: 5 years ago. Start using jest-create-mock-instance in your project by running `npm i jest-create-mock-instance`. There are 6 other projects in the npm registry using jest-create-mock-instance.
      » npm install jest-create-mock-instance
    
Published   Nov 19, 2021
Version   2.0.0
Top answer
1 of 11
527

Using jest.spyOn() is the proper Jest way of mocking a single method and leaving the rest be. Actually there are two slightly different approaches to this.

1. Modify the method only in a single object

Copyimport Person from "./Person";

test('Modify only instance', () => {
    let person = new Person('Lorem', 'Ipsum');
    let spy = jest.spyOn(person, 'sayMyName').mockImplementation(() => 'Hello');

    expect(person.sayMyName()).toBe("Hello");
    expect(person.bla()).toBe("bla");

    // unnecessary in this case, putting it here just to illustrate how to "unmock" a method
    spy.mockRestore();
});

2. Modify the class itself, so that all the instances are affected

Copyimport Person from "./Person";

beforeAll(() => {
    jest.spyOn(Person.prototype, 'sayMyName').mockImplementation(() => 'Hello');
});

afterAll(() => {
    jest.restoreAllMocks();
});

test('Modify class', () => {
    let person = new Person('Lorem', 'Ipsum');
    expect(person.sayMyName()).toBe("Hello");
    expect(person.bla()).toBe("bla");
});

And for the sake of completeness, this is how you'd mock a static method:

Copyjest.spyOn(Person, 'myStaticMethod').mockImplementation(() => 'blah');
2 of 11
56

Edit 05/03/2021

I see a number of people disagree with the below approach, and that's cool. I do have a slight disagreement with @blade's approach, though, in that it actually doesn't test the class because it's using mockImplementation. If the class changes, the tests will still always pass giving false positives. So here's an example with spyOn.

Copy// person.js
export default class Person {
  constructor(first, last) {
      this.first = first;
      this.last = last;
  }
  sayMyName() {
      return this.first + " " + this.last; // Adjusted to return a value
  }
  bla() {
      return "bla";
  }
}

and the test:

Copyimport Person from './'

describe('Person class', () => {
  const person = new Person('Guy', 'Smiley')

  // Spying on the actual methods of the Person class
  jest.spyOn(person, 'sayMyName')
  jest.spyOn(person, 'bla')
  
  it('should return out the first and last name', () => {  
    expect(person.sayMyName()).toEqual('Guy Smiley') // deterministic 
    expect(person.sayMyName).toHaveBeenCalledTimes(1)
  });
  it('should return bla when blah is called', () => {
    expect(person.bla()).toEqual('bla')
    expect(person.bla).toHaveBeenCalledTimes(1)
  })
});

Cheers! 🍻


I don't see how the mocked implementation actually solves anything for you. I think this makes a bit more sense

Copyimport Person from "./Person";

describe("Person", () => {
  it("should...", () => {
    const sayMyName = Person.prototype.sayMyName = jest.fn();
    const person = new Person('guy', 'smiley');
    const expected = {
      first: 'guy',
      last: 'smiley'
    }

    person.sayMyName();

    expect(sayMyName).toHaveBeenCalledTimes(1);
    expect(person).toEqual(expected);
  });
});
🌐
GitHub
github.com › asvetliakov › jest-create-mock-instance
GitHub - asvetliakov/jest-create-mock-instance: Create mock instances with Jest · GitHub
import createMockInstance from "jest-create-mock-instance"; import { Food } from "../food"; let food: jest.Mocked<Food>; beforeEach(() => { food = createMockInstance(Food); });
Starred by 33 users
Forked by 4 users
Languages   JavaScript
🌐
DEV Community
dev.to › c0xxxtv › mock-class-constructor-in-jest-test-with-mocking-partials-1dd5
Mock Class Constructor in Jest Test with Mocking Partials - DEV Community
June 20, 2024 - Here’s a guide on how to do it ... ClassA(arg) } In the test, you want to verify that the function abc returns a new instance of ClassA and that the ClassA constructor is called with arg....
🌐
Kulshekhar
kulshekhar.github.io › mock es6 class
Mock ES6 class | ts-jest
April 5, 2026 - ts-jest · Version: 29.4 · TypeScript is transpiling your ts file and your module is likely being imported using ES2015s import. const soundPlayer = require('./sound-player'). Therefore creating an instance of the class that was exported as a default will look like this: new soundPlayer.default(). However if you are mocking the class as suggested by the documentation.
🌐
GitHub
github.com › jestjs › jest › issues › 14974
[Feature]: Auto mock class / object · Issue #14974 · jestjs/jest
March 18, 2024 - const mockAnotherService = jest.mock(AnotherService); const mockInstance = jest.instance(mockAnotherService); const myService = new MyService(mockInstance); It's delightful with focus on simplicity.
Author   jestjs
Top answer
1 of 2
28

You don't have to mock your mailer class but the mailgun-js module. So mailgun is a function that returns the function messages that return the function send. So the mock will look like this.

for the happy path

const happyPath = () => ({
  messages: () => ({
    send: (args, callback) => callback()
  })
})

for the error case

const errorCase = () => ({
  messages: () => ({
    send: (args, callback) => callback('someError')
  })
})

as you have this 2 cases it make sense to mock the module inside your test. First you have to mock it with a simple spy where we later can set the implementation for our cases and then we have to import the module.

jest.mock('mailgun-js', jest.fn())
import mailgun from 'mailgun-js'
import Mailer from '../../../../server/services/emails/mailer'

As your module uses promises we have 2 options either return the promise from the test or use async/await. I use the later one for more info have a look here.

test('test the happy path', async() => {
 //mock the mailgun so it returns our happy path mock
  mailgun.mockImplementation(() => happyPath)
  //we need to use async/awit here to let jest recognize the promise
  const send = await Mailer.send();
  expect(send).toBe('The email was sent successfully!')
});

If you would like to test that the mailgun send method was called with the correct parameter you need to adapt the mock like this:

const send = jest.fn((args, callback) => callback())
const happyPath = () => ({
  messages: () => ({
    send: send
  })
})

Now you could check that the first parameter for send was correct:

expect(send.mock.calls[0][0]).toMatchSnapshot()
2 of 2
19

Just for Googlers and future visitors, here's how I've setup jest mocking for ES6 classes. I also have a working example at github, with babel-jest for transpiling the ES module syntax so that jest can mock them properly.

__mocks__/MockedClass.js

const stub = {
  someMethod: jest.fn(),
  someAttribute: true
}

module.exports = () => stub;

Your code can call this with new, and in your tests you can call the function and overwrite any default implementation.

example.spec.js

const mockedClass = require("path/to/MockedClass")(); 
const AnotherClass = require("path/to/AnotherClass");
let anotherClass;

jest.mock("path/to/MockedClass");

describe("AnotherClass", () => {
  beforeEach(() => {
    mockedClass.someMethod.mockImplementation(() => {
      return { "foo": "bar" };
    });

    anotherClass = new AnotherClass();
  });

  describe("on init", () => {
    beforeEach(() => { 
      anotherClass.init(); 
    });

    it("uses a mock", () => {
      expect(mockedClass.someMethod.toHaveBeenCalled();
      expect(anotherClass.settings)
        .toEqual(expect.objectContaining({ "foo": "bar" }));
    });
  });

});
🌐
Medium
krantibrid.medium.com › mocking-in-jest-9148fc5fcd73
Mocking in Jest. The goal for mocking is to replace… | by Krantibrid | Medium
October 19, 2020 - The 4 ways to create an ES6 class mock ... Automatic mocks Calling jest.mock(‘…’) returns a useful “automatic mock” you can use to spy on calls to the class constructor and all of its methods