测试调用异步功能的组件

时间:2018-08-06 12:07:28

标签: javascript reactjs unit-testing sinon stub

我有一个react组件,它调用作为道具传入的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设置上做错了什么吗?还是我期望的?感觉像是些小事,但我无法确定

1 个答案:

答案 0 :(得分:1)

您说的没错,只需要做一点改动:

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

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

给事件循环一个循环的机会,这样回调就有机会执行,这应该可以解决问题。可以通过使测试函数异步并等待已解决的Promise(要暂停测试并执行所有排队的回调)来实现:

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)

});