问题
I'm trying test my container component methods. My container had a async method that load all proposals and set in the state. Example.:
loadProposal(proposalId) {
return axios
.get("http://localhost:9292/api/proposal_drafts/1.json")
.then(response => {
this.setState({
proposal: Immutable.fromJS(response.data)
})
})
}
So, to test this method i get the component instance and call the method (the api url is mocked).
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()
})
})
But i get this error from console:
Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
Ops: If i put a console.log(wrapper.state()) inside then() . The log shows my state correctly.
回答1:
If chai.expect()
throws an error (which I think is what's happening), two things will happen:
done
won't get called, because of the thrown error;- the error won't get caught, because there's not additional error handling.
You should use Mocha's promise support instead to remove both issues:
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)
})
})
回答2:
You can also use chai-as-promised
you can write code that expresses what you really mean:
return doSomethingAsync().should.eventually.equal("foo");
or if you have a case where return
is not preferable (e.g. style considerations) or not possible (e.g. the testing framework doesn't allow returning promises to signal asynchronous test completion), then you can use the following workaround (where done()
is supplied by the test framework):
doSomethingAsync().should.eventually.equal("foo").notify(done);
来源:https://stackoverflow.com/questions/39103332/async-tests-mocha-and-chai-ensure-the-done-callback-is-being-called