Mock dependency in jest with typescript

前端 未结 9 1047
梦谈多话
梦谈多话 2020-12-07 12:03

When testing a module that has a dependency in a different file. When assigning that module to be jest.Mock typescript gives an error that the method mock

相关标签:
9条回答
  • 2020-12-07 12:44

    There are two solutions, both are casting desired function

    1) Use jest.MockedFunction

    import * as dep from './dependency';
    
    jest.mock('./dependency');
    
    const mockMyFunction = dep.myFunction as jest.MockedFunction<typeof dep.myFunction>;
    

    2) Use jest.Mock

    import * as dep from './dependency';
    
    jest.mock('./dependency');
    
    const mockMyFunction = dep.default as jest.Mock;
    

    There is no difference between these two solutions. The second one is shorter and I would therefore suggest using that one.

    Both casting solutions allows to call any jest mock function on mockMyFunction like mockReturnValue or mockResolvedValue https://jestjs.io/docs/en/mock-function-api.html

    mockMyFunction.mockReturnValue('value');
    

    mockMyFunction can be used normally for expect

    expect(mockMyFunction).toHaveBeenCalledTimes(1);
    
    0 讨论(0)
  • 2020-12-07 12:46

    Here's what I did with jest@24.8.0 and ts-jest@24.0.2:

    source:

    class OAuth {
    
      static isLogIn() {
        // return true/false;
      }
    
      static getOAuthService() {
        // ...
      }
    }
    

    test:

    import { OAuth } from '../src/to/the/OAuth'
    
    jest.mock('../src/utils/OAuth', () => ({
      OAuth: class {
        public static getOAuthService() {
          return {
            getAuthorizationUrl() {
              return '';
            }
          };
        }
      }
    }));
    
    describe('createMeeting', () => {
      test('should call conferenceLoginBuild when not login', () => {
        OAuth.isLogIn = jest.fn().mockImplementationOnce(() => {
          return false;
        });
    
        // Other tests
      });
    });
    

    This is how to mock a non-default class and it's static methods:

    jest.mock('../src/to/the/OAuth', () => ({
      OAuth: class {
        public static getOAuthService() {
          return {
            getAuthorizationUrl() {
              return '';
            }
          };
        }
      }
    }));
    

    Here should be some type conversion from the type of your class to jest.MockedClass or something like that. But it always ends up with errors. So I just used it directly, and it worked.

    test('Some test', () => {
      OAuth.isLogIn = jest.fn().mockImplementationOnce(() => {
        return false;
      });
    });
    

    But, if it's a function, you can mock it and do the type conversation.

    jest.mock('../src/to/the/Conference', () => ({
      conferenceSuccessDataBuild: jest.fn(),
      conferenceLoginBuild: jest.fn()
    }));
    const mockedConferenceLoginBuild = conferenceLoginBuild as 
    jest.MockedFunction<
      typeof conferenceLoginBuild
    >;
    const mockedConferenceSuccessDataBuild = conferenceSuccessDataBuild as 
    jest.MockedFunction<
      typeof conferenceSuccessDataBuild
    >;
    
    0 讨论(0)
  • 2020-12-07 12:46

    Use as jest.Mock and nothing else

    The most concise way of mocking a module exported as default in ts-jest that I can think of really boils down to casting the module as jest.Mock.

    Code:

    import myDep from '../dependency' // No `* as` here
    
    jest.mock('../dependency')
    
    it('does what I need', () => {
      // Only diff with pure JavaScript is the presence of `as jest.Mock`
      (myDep as jest.Mock).mockReturnValueOnce('return')
    
      // Call function that calls the mocked module here
    
      // Notice there's no reference to `.default` below
      expect(myDep).toHaveBeenCalled()
    })
    

    Benefits:

    • does not require referring to the default property anywhere in the test code - you reference the actual exported function name instead,
    • you can use the same technique for mocking named exports,
    • no * as in the import statement,
    • no complex casting using the typeof keyword,
    • no extra dependencies like mocked.
    0 讨论(0)
提交回复
热议问题