我有以下文件: -
target.js
var target = function(repository, logger) {
return {
addTarget : function(target) {
repository.add(target).then(
function (newTarget) {
console.log("added");
logger.info("added");
},
function (err) {
console.log("error");
logger.info("error");
}
);
}
};
};
module.exports = target;
targetTest.js
var chai = require("chai"),
expect = chai.expect,
sinon = require("sinon"),
Promise = require("bluebird"),
baseTarget = require("../target");
describe("target", function(){
it("should log error when it occurs", function() {
var mockRepository = {
add : sinon.stub().returns(Promise.reject(new Error()))
};
var mockLogger = {
info : sinon.spy()
};
var target = baseTarget(mockRepository, mockLogger);
target.addTarget("target");
expect(mockLogger.info.calledWith("error")).to.be.true;
});
});
我遇到的问题是expect(mockLogger.info.calledWith("error")).to.be.true;
返回false
因为存储库上的add
方法是异步的,所以还没有执行。是否有适当的模式。
答案 0 :(得分:2)
这更像是一个关于'Promises如何工作'的问题而不是它们在测试框架中的工作方式 - 答案是它们的行为保持完全相同。
是否有正确执行此操作的模式。
这不是一个模式,而是Promise的构建方式。 then
的每个成功处理程序在最后一次成功时按顺序执行。在您的代码中,我们可以返回通过调用repository#add
创建的Promise,就像您想要使用其结果或在addTarget
之外执行一些外部相关操作一样:
addTarget: function (target) {
return repository
// ^^^^^^
.add(target)
.then(function (newTarget) {
console.log("added");
logger.info("added");
}, function (err) {
console.log("error");
logger.info("error");
});
}
然后将您的期望置于then
内,该addTarget
将在target.addTarget("target").then(function () {
expect(mockLogger.info.calledWith("error")).to.be.true;
cb();
});
中创建的Promise链的所有成员成功执行:
cb
异步测试
您将在上面的示例中注意到还有对函数it
的调用。由于您的测试是异步的,您需要在测试完成时“告诉”测试框架。这通常是通过使用参数声明describe("target", function () {
it("should log error when it occurs", function (cb) {
// ^^^^
});
});
函数来完成的,框架将从该参数推断测试是异步的并传递回调:
String