异步测试 - Mocha 和 Chai - 确保 done() 回调被调用

Async Tests - Mocha and Chai - Ensure the done() callback is being called

我正在尝试测试我的容器组件方法。我的容器有一个异步方法,可以加载所有提案并设置状态。例如:

loadProposal(proposalId) {
    return axios
            .get("http://localhost:9292/api/proposal_drafts/1.json")
            .then(response => {
              this.setState({
                proposal: Immutable.fromJS(response.data)
              })
            })
  }

因此,为了测试此方法,我获取了组件实例并调用了该方法(api url 已被模拟)。

it("sets proposal in the state", (done) => {
    const wrapper = shallow(<Container/>)

    loadProposalRequest(1)

    wrapper.instance().loadProposal(1).then(() => {
      chai.expect(wrapper.state().proposal).to.be(Map)
      done()
    })
  })

但是我从控制台得到这个错误:

Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.

Ops:如果我把 console.log(wrapper.state()) 放在 then() 里面。日志正确显示了我的状态。

如果 chai.expect() 抛出一个错误(我认为这是正在发生的事情),将会发生两件事:

  • done 不会被调用,因为抛出了错误;
  • 错误不会被捕获,因为没有额外的错误处理。

您应该使用 Mocha 的 promise 支持来解决这两个问题:

it("sets proposal in the state", () => {
  const wrapper = shallow(<Container/>)

  loadProposalRequest(1)

  return wrapper.instance().loadProposal(1).then(() => {
    chai.expect(wrapper.state().proposal).to.be(Map)
  })
})

您也可以使用chai-as-promised

您可以编写表达您真正意思的代码:

return doSomethingAsync().should.eventually.equal("foo");

或者,如果您遇到 return 不可取(例如,样式考虑)或不可能(例如,测试框架不允许返回承诺来表示异步测试完成)的情况,那么您可以使用以下解决方法(其中 done() 由测试框架提供):

doSomethingAsync().should.eventually.equal("foo").notify(done);