我是单元测试,mocha和should.js的新手,我正在尝试为返回promise的异步方法编写测试。这是我的测试代码:
var should = require("should"),
tideRetriever = require("../tide-retriever"),
moment = require("moment"),
timeFormat = "YYYY-MM-DD-HH:mm:ss",
from = moment("2013-03-06T00:00:00", timeFormat),
to = moment("2013-03-12T23:59:00", timeFormat),
expectedCount = 300;
describe("tide retriever", function() {
it("should retrieve and parse tide CSV data", function() {
tideRetriever.get(from, to).then(
function(entries) { // resolve
entries.should.be.instanceof(Array).and.have.lengthOf(expectedCount);
},
function(err) { // reject
should.fail("Promise rejected", err);
}
);
});
});
当我手动测试tideRetriever.get
方法时,它会一致地解析一个包含27个元素的数组(如预期的那样),但无论expectedCount
的值如何,测试都不会失败。这是我简单的手动测试:
tideRetriever.get(from, to).then(
function(entries) {
console.log(entries, entries.length);
},
function(err) {
console.log("Promise rejected", err);
}
);
如果有必要,我也可以发布正在测试的模块的源代码。
我是否误解了摩卡或者应该是什么?任何帮助将不胜感激。
答案 0 :(得分:7)
更新
在某些时候,Mocha开始支持从测试中返回Promise
而不是添加done()
回调。原始答案仍然有效,但测试看起来更干净:
it("should retrieve and parse tide CSV data", function() {
return tideRetriever.get(from, to).then(
function(entries) {
entries.should.be.instanceof(Array).and.have.lengthOf(expectedCount);
}
);
});
查看this gist以获取完整示例。
ORIGINAL
<强>注意即可。接受的答案仅适用于普通的异步代码,而不适用于Promises(作者使用)。
区别在于Promise回调抛出的异常不能被应用程序捕获(在我们的例子中是Mocha),因此测试将因超时而不是实际断言而失败。根据Promise实现,可以记录或不记录断言。请参阅when documentation。
,详细了解相关信息要使用Promises正确处理此问题,您应该将err
对象传递给done()
回调而不是抛出它。您可以使用Promise.catch()
方法(不在onRejection()
的{{1}}回调中)执行此操作,因为它不会捕获同一方法的Promise.then()
回调中的异常。见下面的例子:
onFulfilment()
PS describe("tide retriever", function() {
it("should retrieve and parse tide CSV data", function(done) {
tideRetriever.get(from, to).then(
function(entries) { // resolve
entries.should.be.instanceof(Array).and.have.lengthOf(expectedCount);
done(); // test passes
},
function(err) { // reject
done(err); // Promise rejected
}
).catch(function (err) {
done(err); // should throwed assertion
});
});
});
回调用于三个地方以涵盖所有可能的情况。但是,如果您不需要任何特殊逻辑,则可以完全删除done()
回调。在这种情况下,onRejection()
也会处理拒绝。
答案 1 :(得分:4)
在测试异步代码时,您需要在测试完成时告诉Mocha(无论是通过还是失败)。这是通过为测试函数指定一个参数来完成的,Mocha使用done
函数填充该参数。所以你的代码可能如下所示:
describe("tide retriever", function() {
it("should retrieve and parse tide CSV data", function(done) {
tideRetriever.get(from, to).then(
function(entries) { // resolve
entries.should.be.instanceof(Array).and.have.lengthOf(expectedCount);
done();
},
function(err) { // reject
should.fail("Promise rejected", err);
done();
}
);
});
});
请注意,Mocha知道这种情况的方式是异步测试,需要等到调用done()
时才指定该参数。
此外,如果您的承诺有一个“已完成”的处理程序,它会在成功和失败时触发,您也可以在其中调用done()
,从而保存一个电话。