我正在使用承诺在(expressJS)路由的末尾包装异步(Mongo) DB。我想试着找出如何测试以下代码。
userService
userService.findOne = function (id) {
var deferred = q.defer();
User.findOne({"_id" : id})
.exec(function (error, user) {
if (error) {
deferred.reject(error);
} else {
deferred.resolve(user);
}
});
return deferred.promise;
};userRoute
var user = function (req, res) {
var userId = req.params.id
, userService = req.load("userService");
// custom middleware that enables me to inject mocks
return userService.findOne(id)
.then(function (user) {
console.log("called then");
res.json({
msg: "foo"
});
}).catch(function (error) {
console.log("called catch");
res.json({
error: error
});
}).done();
};下面是用摩卡测试上述内容的一次尝试
userTest
it("when resolved", function (done) {
var jsonSpy = sinon.spy(httpMock.res, "json")
, httpMock = require("/path/to/mock/http/object")
, serviceMock = require("/path/to/mock/service"),
, deferred = q.defer()
, findStub = sinon.stub(serviceMock, "findOne")
.returns(deferred.promise)
, loadStub = sinon.stub(httpMock.req, "load")
.returns(serviceMock),
retPromise;
// trigger route
routes.user(httpMock.req, httpMock.res);
// force promise to resolve?
deferred.resolve();
expect(jsonSpy.called).to.be.true; // fails
// chai as promised
retPromise = findStub.returnValues[0];
expect(retPromise).to.be.fulfilled; // passes
});http模拟只是一个空对象,没有操作,expressJS通常会在其中开始呈现内容。我在那些禁闭室里增加了一些日志,以了解这件事是如何联系在一起的。
这不太好用。我想验证整个系统是如何集成的,建立某种回归套件--但是我实际上已经把它模拟成了碎片,我只是在测试我的模型(在这个过程中并不完全成功)。
我还注意到,在我的http模拟中触发的控制台日志和catch正在触发两次--但是在实际代码中调用的jsonSpy (通过在userRoute代码中注销sinon间谍来验证)不会在测试中调用。
有没有人对蒙戈支持的快递应用的集成测试策略有一些建议?
发布于 2014-04-11 18:17:27
在我看来,你似乎没有给你的承诺一个解雇的机会,在你检查结果是否已经发出。您需要异步等待userService.findOne()的承诺链完成,然后才能设置jsonSpy.called。
// start of code as normal
q.when(
routes.user(httpMock.req, httpMock.res),
function() { expect(jsonSpy.called).to.be.true; }
);
deferred.resolve();
// rest of code as normal这应该是routes.user()承诺的连锁,并按预期通过。
注意一点:我不熟悉您的框架,所以我不知道它是否会耐心地等待所有异步事件的发生。如果这会使您在回拨延迟链时遇到问题,您可能需要尝试节点单元,它很好地处理异步测试(IMO)。
https://stackoverflow.com/questions/22822356
复制相似问题