【问题标题】:Jest mock a module to produce different results on function calls开玩笑模拟一个模块以在函数调用上产生不同的结果
【发布时间】:2021-07-12 18:00:01
【问题描述】:

我有一个模块:

// foo.js
module.exports = async () => {
  ...
}

这个模块在另一个模块中被调用,我正在测试哪个行为:

// bar.js
const one = await foo();
const two = await foo();

我想用 Jest 模拟 foo,以便对其进行多次调用返回不同的结果。更准确地说,第一次调用成功,第二次返回错误。

这是我的模拟机制:

const fooMock = jest.mock('../src/foo')
fooMock
  .mockImplementationOnce(() => Promise.resolve({ id: 'asdf' }))
  .mockImplementationOnce(() => Promise.reject(new Error('some error')))

问题是mockImplementationOnce 不是jest.mock() 的函数。它只是jest.fn() 的一个功能。 jest.mock() 对象只有mockImplementation,它将模拟和密封模拟函数的返回结果,并且不允许多次调用时产生不同的结果。

如何模拟模块以在第一次和第二次调用时返回不同的结果?

灵感来自the jest docs here

更新:

我也试过这种方法:

  jest.mock('../src/foo', () => jest.fn()
      .mockImplementationOnce(() => Promise.resolve({ _id: 'asdf' }))
      .mockImplementationOnce(() => Promise.reject('some error'))
  )

但现在根本没有嘲笑。

【问题讨论】:

    标签: javascript unit-testing jestjs mocking


    【解决方案1】:

    你应该使用mockFn.mockReturnValueOnce(value):

    接受将在一次调用模拟函数时返回的值。可以链接,以便对模拟函数的连续调用返回不同的值

    在调用jest.mock('./src/foo')后,你应该导入./src/foo模块,它将是一个模拟版本,而不是使用返回值。

    const fooMock = require('./src/foo');
    
    jest.mock('./src/foo');
    
    test('should pass', () => {
      fooMock.mockReturnValue('default')
             .mockReturnValueOnce('first call')
             .mockReturnValueOnce('second call')
    
      // 'first call', 'second call', 'default', 'default'
      console.log(fooMock(), fooMock(), fooMock(), fooMock());
    })
    

    【讨论】:

    • 好的,它是这样工作的,但现在问题是我正在测试的模块中所需的foo 模块的实例没有被模拟。我在这里想念什么吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-31
    • 2017-01-30
    • 2020-03-05
    • 1970-01-01
    • 2020-01-31
    • 1970-01-01
    • 2023-03-17
    相关资源
    最近更新 更多