unit-testingjestjs

How can I mock a single class in a module while preserving its structure using Jest?


I have a module (called myModule) which exports two classes (MyClass1 and MyClass2). I'm trying to mock a single class (MyClass1) from myModule using Jest, but I want the mock to preserve the structure of the original class — including its methods — without manually redefining them.

I know that this works:

jest.mock('myModule');

With this, MyClass1 is automatically mocked and its methods are replaced with mock functions, the same applies to MyClass2. This is great.

However, I want to only mock MyClass1 while keeping the rest of the module's exports intact (here MyClass2). So I tried:

jest.mock('myModule', () => ({
  ...jest.requireActual('myModule'),
  MyClass1: jest.fn(),
}));

This keeps MyClass2 intacts but it replaces MyClass1 with a plain mock function, and the resulting instance has no methods — it's just an empty mock object. I don’t want to manually define the mock implementation like this:

jest.mock('myModule', () => ({
  ...jest.requireActual('myModule'),
  MyClass1: jest.fn().mockImplementation(() => ({
    filter: jest.fn(),
}));

I want Jest to automatically mock the class structure, like it does with jest.mock('./module').

Is there a way to achieve this — mocking only one class in a module, while preserving its structure automatically (its methods replaced with mock functions)?


Solution

  • In fact, you can achieve it by using createMockFromModule():

    jest.mock('myModule', () => {
      const mockModule: any = jest.createMockFromModule('myModule');
      return {
        ...jest.requireActual('myModule'),
        MyClass1: mockModule.MyClass1,
      };
    });
    const myClass1Mock = jest.mocked(MyClass1);
    

    Like this, MyClass1 constructor and methods are mocked and MyClass2 is not mocked at all, as expected.