如何在Jest的同一测试文件中的不同测试中以不同的方式模拟模块?

时间:2020-11-03 19:12:14

标签: javascript unit-testing jestjs mocking

目前我有这个:

jest.mock('my/hook', () => () => false)

我希望我的自定义React钩子模块默认在每个测试中返回false,但在一些测试中,我希望它返回true。

该钩子基本上是这样实现的:

function useMyHook(key) {
  switch (key) {
    case 'foo':
    case 'bar':
      return true
    default:
      return false
  }
}

我在组件中多次使用了该钩子,一次用于foo键,一次用于bar键。我希望它默认为两个键都返回false。

但是对于一些测试,我希望foo键返回true,对于其他测试,我希望bar键返回true。

我通过在特定测试中执行此操作来进行了尝试,但是它什么也没做:

it('should do x', () => {
  jest.doMock('my/hook', () => (key) => {
    if (key == 'foo') {
      return true
    }
  })
  // ... rest of test
})

如何在Jest中按测试自定义模块模拟?

1 个答案:

答案 0 :(得分:0)

jest.doMock本身无法执行任何操作,因为依赖它的模块已在较早时导入。之后应重新导入它,并用jest.resetModulesjest.isolateModules丢弃模块缓存:

beforeEach(() => {
  jest.resetModules();
});

it('should do x', () => {
  jest.doMock('my/hook', ...)
  require('module that depends on hook');
  // ... rest of test
})

由于需要对函数进行不同的模拟,因此更好的方法是使用Jest间谍而不是普通函数模拟实现:

jest.mock('my/hook', () => jest.fn(() => false))
...
it('should do x', () => {
  hook.mockReturnValueOnce(true);
  // ... rest of test
})