我无法追查为什么没有触发一个罪人间谍。在下面的测试中,两个控制台语句都报告为false,因此没有调用任何方法(如果有错误)。
这是我的一个mocha测试通常的样子:
DECLARE
i varchar2(3000) := dbms_random.string('A',8);
BEGIN
INSERT INTO BUYERS
(USER_ID,BUYER_CD,BUYER_ENG_NM,REG_DT)
VALUES
(i,'tes','test','test');
EXCEPTION WHEN OTHER
THEN
--by the time you got here there is no point in trying to insert again
LOG_ERROR(SQLERRM, LOCATION);
RAISE;
end;
});
PostContoller中的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();
});
});
});
方法:
readAllPosts
最后是PostModel中的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);
}
}
);
}
};
方法:
find
如果我以正常方式调用方法,则执行find,返回预期的Posts数组。但是Posts.find= function (conditions, cb) {
/* ... */
dbQuery(query, function (err, results) {
if (err) {
cb(err);
}
cb(null, results);
});
};
间谍从未被执行过。此外,如果我将控制器类中的方法更改为此
res
间谍功能(res)会发射。我知道发送给模型的回调被调用,res对象在那里,但它没有被调用。我不认为这是一个间接问题(调用原始方法而不是sinon包装)但我不确定问题出在哪里。
答案 0 :(得分:0)
使用Sinon间谍/存根测试异步函数很困难,因为(AFAIK)你不能告诉你何时调用它(它甚至可能永远不会被调用)。
在您的情况下,您假设PostModel.find()
将在下一个勾号中完成(根据您使用process.nextTick()
判断),这很可能不是这样,所以当查询仍在运行时,您将检查您的间谍,并且还没有调用任何间谍。
在我看来,您尝试使用一个测试进行过多测试:PostModel.find()
,dbQuery()
和controller.readAllPosts()
。我可能会将它们分成不同的测试,然后将其余的测试分开。
因此,例如,如果要检查控制器是否发回正确的响应,或者它是否正确处理错误,请将PostModel.find()
存在以使其以错误或正确的方式调用回调(同步)结果数组,然后检查res.send/res.json
间谍。
另一种选择是不使用间谍,而是使用简单的回调。例如:
controller.readAllPosts(req, {
send : function(data) {
assert(data, ...);
done();
},
json : function(data) {
assert(data, ...);
done();
},
});
(或其变体)
但是,我不想这样做,因为它会阻止您(以一种简单的方式)测试,例如,这些方法的两个都被调用了。