我无法追查为什么没有触发一个罪人 Spy . 在下面的测试中,两个控制台语句都报告为false,因此没有调用任何方法(如果有错误) .
这是我的一个mocha测试通常看起来像:
describe('Post Controller', function () {
var controller = require('../controllers/PostController'),
req = {
user: {
check_id: "00100",
access_id: "54876329"
}
};
beforeEach(function () {
res = {
send: sinon.spy(),
json: sinon.spy()
};
});
afterEach(function () {
res.send.reset();
});
describe('readAllPosts', function () {
it('should return an array of posts', function (done) {
controller.readAllPosts(req, res);
process.nextTick(function () {
console.log('send: ', res.send.called);
console.log('json: ', res.json.called);
assert(res.json.calledWith(sinon.match.array));
done();
});
});
});
});
PostContoller中的 readAllPosts
方法:
var postController = {
readAllPosts: function (req, res) {
PostModel.find(
{
access_id: req.user.access_id
},
function (err, results) {
if (err) {
res.send(404, err);
} else {
// res here is a spy
res.json(results);
}
}
);
}
};
最后是PostModel中的 find
方法:
Posts.find= function (conditions, cb) {
/* ... */
dbQuery(query, function (err, results) {
if (err) {
cb(err);
}
cb(null, results);
});
};
如果我以正常方式调用方法,则执行find,返回预期的Posts数组 . 但是 res
Spy 永远不会被执行 . 此外,如果我将控制器类中的方法更改为此
var postController = {
readAllPosts: function (req, res) {
res.json([{this:"that",and:"other"}]);
}
};
Spy 功能(res)起火 . 我知道发送给模型的回调正在被调用,并且res对象在那里,但它认为这是一个间接问题(调用原始方法而不是sinon包装的)但我不确定问题出在哪里所在 .
1 回答
使用Sinon Spy /存根测试异步函数很困难,因为(AFAIK)你无法告诉你它何时被调用(它甚至可能永远不会被调用) .
在你的情况下,你假设
PostModel.find()
将在下一个勾号中完成(通过使用process.nextTick()
判断),当查询仍然在运行时,很可能不会检查你的 Spy ,并且还没有调用任何 Spy .在我看来,你试图用一个测试来测试太多:
PostModel.find()
,dbQuery()
和controller.readAllPosts()
. 我可能会将它们分成不同的测试,然后将其余的测试分开 .因此,例如,如果要检查控制器是否发回正确的响应,或者它是否正确处理错误,则使用
PostModel.find()
让它与错误或正确的结果数组一起调用(同步)回调,然后检查res.send/res.json
Spy .另一种选择是不使用 Spy ,而是使用简单的回调 . 例如:
(或其变体)
但是,我不想这样做,因为它会阻止您(以一种简单的方式)测试,例如,不是这两种方法都被调用 .