How to change mock implementation on a per single test basis [Jestjs]

前端 未结 3 1923
太阳男子
太阳男子 2020-12-12 12:42

I\'d like to change the implementation of a mocked dependency on a per single test basis by extending the default mock\'s

相关标签:
3条回答
  • 2020-12-12 12:47

    Little late to the party, but if someone else is having issues with this.

    We use TypeScript, ES6 and babel for react-native development.

    We usually mock external NPM modules in the root __mocks__ directory.

    I wanted to override a specific function of a module in the Auth class of aws-amplify for a specific test.

        import { Auth } from 'aws-amplify';
        import GetJwtToken from './GetJwtToken';
        ...
        it('When idToken should return "123"', async () => {
          const spy = jest.spyOn(Auth, 'currentSession').mockImplementation(() => ({
            getIdToken: () => ({
              getJwtToken: () => '123',
            }),
          }));
    
          const result = await GetJwtToken();
          expect(result).toBe('123');
          spy.mockRestore();
        });
    

    Gist: https://gist.github.com/thomashagstrom/e5bffe6c3e3acec592201b6892226af2

    Tutorial: https://medium.com/p/b4ac52a005d#19c5

    0 讨论(0)
  • 2020-12-12 12:56

    A nice pattern for writing test is to create a setup factory function that returns the data you need for testing the current module.

    Below is some sample code following your second example although allows the provision of default and override values in a reusable way.

    const spyReturns = returnValue => jest.fn(() => returnValue);
    
    describe("scenario", () => {
      const setup = (mockOverrides) => {
        const mockedFunctions =  {
          a: spyReturns(true),
          b: spyReturns(true),
          ...mockOverrides
        }
        return {
          mockedModule: jest.doMock('../myModule', () => mockedFunctions)
        }
      }
    
      it("should return true for module a", () => {
        const { mockedModule } = setup();
        expect(mockedModule.a()).toEqual(true)
      });
    
      it("should return override for module a", () => {
        const EXPECTED_VALUE = "override"
        const { mockedModule } = setup({ a: spyReturns(EXPECTED_VALUE)});
        expect(mockedModule.a()).toEqual(EXPECTED_VALUE)
      });
    });
    
    0 讨论(0)
  • 2020-12-12 12:56

    Vanilla JS

    Use mockFn.mockImplementation(fn).

    import { funcToMock } from './somewhere';
    jest.mock('./somewhere');
    
    beforeEach(() => {
      funcToMock.mockImplementation(() => { /* default implementation */ });
    });
    
    test('case that needs a different implementation of funcToMock', () => {
      funcToMock.mockImplementation(() => { /* implementation specific to this test */ });
      // ...
    });
    

    TypeScript

    In addition to the Vanilla JS solution:

    To prevent the message mockImplementation is not a property of funcToMock, you will need to specify the type, e.g. by changing the top line from above to the following:

    import { (funcToMock as jest.Mock) } from './somewhere';
    

    A question addressing this issue can be found here: jest typescript property mock does not exist on type

    0 讨论(0)
提交回复
热议问题