我发现仅仅增加超时的“解决方案”掩盖了这里真正发生的事情,要么
- 您的代码和/或网络调用太慢了(应该低于 100 毫秒以获得良好的用户体验)
- 断言(测试)失败,并且在 Mocha 能够对错误采取行动之前,某些东西正在吞噬错误。
当 Mocha 没有从回调中收到断言错误时,您通常会遇到 #2。这是由一些其他代码将异常进一步吞入堆栈引起的。处理这个问题的正确方法是修复代码而不是吞下错误。
当外部代码吞噬你的错误时
如果它是您无法修改的库函数,您需要自己捕获断言错误并将其传递给 Mocha。为此,您可以将断言回调包装在 try/catch 块中,并将任何异常传递给 done 处理程序。
it('should not fail', function (done) { // Pass reference here!
i_swallow_errors(function (err, result) {
try { // boilerplate to be able to get the assert failures
assert.ok(true);
assert.equal(result, 'bar');
done();
} catch (error) {
done(error);
}
});
});
这个样板当然可以提取到一些实用函数中,以使测试更令人赏心悦目:
it('should not fail', function (done) { // Pass reference here!
i_swallow_errors(handleError(done, function (err, result) {
assert.equal(result, 'bar');
}));
});
// reusable boilerplate to be able to get the assert failures
function handleError(done, fn) {
try {
fn();
done();
} catch (error) {
done(error);
}
}
加快网络测试
除此之外,我建议您参考有关开始使用测试存根进行网络调用以使测试通过而不必依赖正常运行的网络的建议。使用 Mocha、Chai 和 Sinon 的测试可能看起来像这样
describe('api tests normally involving network calls', function() {
beforeEach: function () {
this.xhr = sinon.useFakeXMLHttpRequest();
var requests = this.requests = [];
this.xhr.onCreate = function (xhr) {
requests.push(xhr);
};
},
afterEach: function () {
this.xhr.restore();
}
it("should fetch comments from server", function () {
var callback = sinon.spy();
myLib.getCommentsFor("/some/article", callback);
assertEquals(1, this.requests.length);
this.requests[0].respond(200, { "Content-Type": "application/json" },
'[{ "id": 12, "comment": "Hey there" }]');
expect(callback.calledWith([{ id: 12, comment: "Hey there" }])).to.be.true;
});
});
有关更多信息,请参阅Sinon 的nise
文档。