测试调用异步函数的组件

Testing a component which calls an async function

我有一个 react 组件,它调用作为 prop 传入的 async 函数,然后调用 then 函数中的另一个函数。

我在下面对其进行了简化以作为说明。

例如

const Form = ({ doSomething, closeModal }) => 
<form onSubmit={(e) => {doSomething().then(() => closeModal())
}}>
...
</form>

我正在尝试测试 closeModal 是这样调用的:

it('should doSomething then call closeModal', () => {

  const doSomethingStub = sinon.stub().resolves()
  const closeModalStub = sinon.stub()

  const props = {
    doSomething: doSomethingStub,
    closeModal: closeModalStub
  }

  const wrapper = shallow(<Form {...props}/>)

  wrapper.find(`form`).simulate(`submit`)

  expect(doSomethingStub.called).toEqual(true)
  expect(closeModalStub.called).toEqual(true)

})

在我的例子中,只有第一个期望是正确的。我在 sinon.stub 设置上做错了吗?或者我在期待什么?感觉有点小问题,但我无法确定

你完全正确,它只需要一个小改动:

then 将回调排队等待执行。当前同步代码完成时执行回调,事件循环获取下一个排队的内容。

测试 运行 完成,但在 thenonSubmit() 中排队的回调有机会 运行 之前失败。

给事件循环一个循环的机会,这样回调就有机会执行,这应该可以解决问题。这可以通过使您的测试函数异步并等待您想要暂停测试并让任何排队的回调执行的已解决承诺来完成:

it('should doSomething then call closeModal', async () => {

  const doSomethingStub = sinon.stub().resolves()
  const closeModalStub = sinon.stub()

  const props = {
    doSomething: doSomethingStub,
    closeModal: closeModalStub
  }

  const wrapper = shallow(<Form {...props}/>)

  wrapper.find(`form`).simulate(`submit`);

  // Pause the synchronous test here and let any queued callbacks execute
  await Promise.resolve();

  expect(doSomethingStub.called).toEqual(true)
  expect(closeModalStub.called).toEqual(true)

});