How to use jest to mock a function just for some specified arguments, but uses its original logic for any other arguments?

Say I have a function:

function complexCompute(num: number): string {
   switch(num) {
      case 1: return '...something...';
      case 2: return '...something...';
      case 3: return '...something...';
      // more cases
}

It is used many times in the code I want to test, but I want to mock it like this:

  • when I pass the argument num is 1, complexCompute returns my mocked string my-mock-string1
  • when I pass any other argument, it uses its original logic

I can't find a way to do it, since if I mocked the module:

jest.mock('./complexCompute')

The mocked complexCompute doesn't have original logic. I have to define the mock value for argument 1, and also rewrite the whole logic for other arguments.

Is there any way to do it?

1 answer

  • answered 2021-03-09 06:47 Teneff

    To access the actual implementation for a mocked module you can use jest.requireActual(moduleName).

    Here are two examples:

    Mocking the entire module
    jest.mock('./complexCompute', () => {
      const actual = jest.requireActual('./complexCompute').default;
    
      return {
        default: (arg: number): string => arg === 1 ? 'my-mock-string1' : actual(arg)
      }
    })
    
    Using auto-mock with .mockImplementation
    import complexCompute from './complexCompute';
    
    jest.mock('./complexCompute')
    
    complexCompute.mockImplementation((arg) => {
      return arg === 1
        ? 'my-mock-string1'
        : jest.requireActual('./complexCompute').default(arg)
    });
    
    

    working TypeScript example