Jest mock inner function

后端 未结 5 2124
清歌不尽
清歌不尽 2020-11-28 06:49

I have one file called helper.js that consist of two functions

export const funcA = (key) => {
   return funcB(key)
};

export const func         


        
相关标签:
5条回答
  • 2020-11-28 07:21

    If an ES6 module directly exports two functions (not within a class, object, etc., just directly exports the functions like in the question) and one directly calls the other, then that call cannot be mocked.

    In this case, funcB cannot be mocked within funcA the way the code is currently written.

    A mock replaces the module export for funcB, but funcA doesn't call the module export for funcB, it just calls funcB directly.


    Mocking funcB within funcA requires that funcA call the module export for funcB.

    That can be done in one of two ways:


    Move funcB to its own module

    funcB.js

    export const funcB = () => {
      return 'original';
    };
    

    helper.js

    import { funcB } from './funcB';
    
    export const funcA = () => {
      return funcB();
    };
    

    helper.spec.js

    import * as funcBModule from './funcB';
    import { funcA } from './helper';
    
    describe('helper', () => {
    
      test('test funcB', () => {
        expect(funcBModule.funcB()).toBe('original');  // Success!
      });
    
      test('test funcA', () => {
        const spy = jest.spyOn(funcBModule, 'funcB');
        spy.mockReturnValue('mocked');
    
        expect(funcA()).toBe('mocked');  // Success!
    
        spy.mockRestore();
      });
    });
    

    Import the module into itself

    "ES6 modules support cyclic dependencies automatically" so it is perfectly valid to import a module into itself so that functions within the module can call the module export for other functions in the module:

    helper.js

    import * as helper from './helper';
    
    export const funcA = () => {
      return helper.funcB();
    };
    
    export const funcB = () => {
      return 'original';
    };
    

    helper.spec.js

    import * as helper from './helper';
    
    describe('helper', () => {
    
      test('test funcB', () => {
        expect(helper.funcB()).toBe('original');  // Success!
      });
    
      test('test funcA', () => {
        const spy = jest.spyOn(helper, 'funcB');
        spy.mockReturnValue('mocked');
    
        expect(helper.funcA()).toBe('mocked');  // Success!
    
        spy.mockRestore();
      });
    });
    
    0 讨论(0)
  • 2020-11-28 07:27
    import * as helper from 'helper';
    
        describe('helper', () => {
           it('should test testFuncA', () => {
              const mockTestFuncB = jest.mock();
              // spy on calls to testFuncB and respond with a mock function
    
               mockTestFuncB.spyOn(helper, 'testFuncB').mockReturnValue(/*your expected return value*/);
    
              // test logic
    
              // Restore helper.testFuncB to it's original function
              helper.testFuncB.mockRestore();
           }
        }
    
    0 讨论(0)
  • 2020-11-28 07:28

    Late answer but this should work. Also you should test funcB in its own file and not inside the 'helper' tests.

    import { funcB } from './funcB';
    import { funcA } from './helper';
    
    jest.mock('./funcB');
    
    describe('helper', () => {
        test('test funcA', () => {
            const funcBSpy = jest.fn();
            funcB.mockImplementation(() => funcBSpy());
    
            expect(funcBSpy).toHaveBeenCalledTimes(1);
        });
    });
    
    0 讨论(0)
  • 2020-11-28 07:29

    I think this might work

    import * as helper from 'helper';
    
    describe('helper', () => {
       test('testFuncB', () => {
    
       }
       test('testFuncA', () => {
          const mockTestFuncB = jest.mock();
          // spy on calls to testFuncB and respond with a mock function
          jest.spyOn(helper, 'testFuncB').mockImplementationOnce(mockTestFuncB);
    
          // Do the testing ...
    
          // Restore helper.testFuncB to it's original function
          helper.testFuncB.mockRestore();
       }
    }
    
    0 讨论(0)
  • 2020-11-28 07:31

    I create a kind of nameSpace to handle this issue:

    let helper = {}
    
    const funcA = (key) => {
       return helper.funcB(key)
    };
    
    const funcB = (key,prop) => {
        return someObj;
    };
    
    helper = { funcA, funcB }
    
    module.exports = helper
    

    and then mocking is obvious with jest.fn

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