Jest - 模拟函数调用

时间:2016-11-23 18:11:03

标签: javascript unit-testing jestjs

我正在尝试模拟一个函数调用,并期望它在其中调用一次其他函数。

myFunctions.test.js

import { resetModal } from '../myFunctions.js';

describe('resetModal', () => {
  it('calls the clearSomethingInModal function', () => {
    const clearSomethingInModal = jest.fn();
    resetCreationModal();
    expect(clearSomethingInModal.mock.calls.length).toBe(1);
  })
})

myFunctions.js

export resetModal() {
  clearSomethingInModal()
}

然而,Jest输出表明它还没有被调用。如果有人能建议如何做到这一点,我将非常感激。

2 个答案:

答案 0 :(得分:27)

您的方法不起作用,因为您只在测试文件的上下文中模拟clearSomethingInModal,因此clearSomethingInModal中的myFunctions.js仍然是原始版本。重点是你不能模仿在myFunctions.js中直接创建的东西。你唯一可以嘲笑的是:

  1. 您导入myFunctions.js的模块,例如import clearSomethingInModal from 'clearSomethingInModal';
  2. 从测试中调用它们时传递给函数的回调;
  3. 如果您将myFunctions.js视为黑盒子,您可以控制其中的内容,例如导入或函数参数,以及您可以在哪里测试出来的内容,这是有道理的。但是你无法测试盒子里面发生的事情。

    以下两个示例反映了列表中的2个点:

    myFunctions.test.js

    import { resetModal } from '../myFunctions.js';
    import clearSomethingInModal from 'clearSomethingInModal';
    
    jest.mock('clearSomethingInModal', () => jest.fn())
    
    describe('resetModal', () => {
      it('calls the clearSomethingInModal function', () => {
        resetCreationModal();
        expect(clearSomethingInModal.mock.calls.length).toBe(1);
      })
    })
    

    myFunctions.js

    import clearSomethingInModal from 'clearSomethingInModal';
    
    export resetModal() {
      clearSomethingInModal()
    }
    

    myFunctions.test.js

    import { resetModal } from '../myFunctions.js';
    
    describe('resetModal', () => {
      it('calls the clearSomethingInModal function', () => {
        const clearSomethingInModal = jest.fn();
        resetCreationModal(clearSomethingInModal);
        expect(clearSomethingInModal.mock.calls.length).toBe(1);
      })
    })
    

    myFunctions.js

    export resetModal(clearSomethingInModal) {
      clearSomethingInModal()
    }
    

答案 1 :(得分:1)

另一种方法是使用 done 并模拟或监视最后一个函数的实现,并检查前一个函数是否被调用。

it('should call function2 after function1', (done) => {
    expect.assertions(2)

    function2.mockImplementationOnce(() => {
      expect(function1).toHaveBeenCalled()
      done()
    })

    act() // This is where you run function you are testing
  })

这个方案的缺点是测试的结构不是

// arrange
// act
// assert

而是

// arrange & assert
// act