我发现仅仅增加超时的“解决方案”掩盖了这里真正发生的事情
你的代码和/或网络调用太慢了(为了获得良好的用户体验,应该低于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文档了解更多信息。