Skip to content Skip to sidebar Skip to footer

Jest Manual Mocking A Package Requiring New Instance

I'm trying to use Jest manual mock to mock the behaviour of a package X used in a project. The usage of package X within the the actual application code is like so: // Real.js im

Solution 1:

There's a complete explanation for doing this with jest.mock('./SomeClass'); that applies to this question. "ES6 class, Automatic mock" . let's get started.

// ./lib/X.jsexportdefaultclassX {
  constructor () {
    this.id = '1234567890';
  }

  doSomething = () => {
    return'Original X';
  }
}

Note, the above code has never been called during the test.

This is the resource we want to test, what I mean is, in this class create objects by the class or module that is mocked. We want to make a fake version instead of the original.

// Real.jsimport X from'./lib/X.js';

exportdefaultclassApp  {
  constructor() {
    this.x = newX(); // creating a new instance of X
  }

  execute = () => {
    this.x.doSomething(); // calling someThing() of X
  }
}

Accepts a function that should be used as the implementation of the mock. So what we will do is using manual mocks ( __ mocks __ folder) to mock ES6 classes.

// ./__mocks__/lib/X.jsmodule.exports = jest.fn().mockImplementation(() => {
  return {
    doSomething: jest.fn(() =>'Mocking Original X'),
    id: (Math.random() * 1000) % 10
  }
});

When we import './lib/X.js' on our test file, Now, in order to test this method without actually hitting the library (and thus creating slow and fragile tests), we immediately use the mock the './lib/X.js' module.

// Real.test.jsimport X from'./lib/X.js';
importRealfrom'./Real';

jest.mock('./lib/X.js'); // // X module is now a mock constructordescribe('Testing', async () => {
  beforeEach(() => {
    // Clear all instances and calls to constructor and all methods:
    X.mockClear();
  });


  it('DoSomething should print mocked correct statement', async () => {
    // Ensure our mockClear() is clearing out previous calls to the constructorexpect(X).not.toHaveBeenCalled(); 

    const real = newReal();
    expect(X).toHaveBeenCalledTimes(1); // Constructor has been called X.js

    real.execute();

    // mock.instances is available with automatic mocks:const mockXInstance = X.mock.instances[0];
    const mockDoSomething = mockXInstance.doSomething;
    expect(mockDoSomething).toHaveBeenCalledTimes(1);
    expect(mockDoSomething.mock.calls[0][0]).toEqual('Mocking Original X');
  });
});

maybe this is not enough to answer, at least this explains how mock works in similar cases

Post a Comment for "Jest Manual Mocking A Package Requiring New Instance"