我很难找到sinon间谍没有被触发的原因。在下面的测试中,两个控制台语句都报告为false,因此两个方法都没有被调用(以防出现错误)。
这是我的一个摩卡测试通常的样子:
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();
});
});
});
});
PostOnToller中的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);
});
};
如果我以正常的方式调用方法,它们会执行查找,返回预期的Posts数组。但是,不会执行res
间谍。另外,如果我将控制器类中的方法更改为
var postController = {
readAllPosts: function (req, res) {
res.json([{this:"that",and:"other"}]);
}
};
间谍函数(res)确实会开火。我知道发送到Model的回调正在被调用,res对象在那里,但它没有被调用。我不认为这是一个间接的问题(调用原始方法而不是sinon包装的方法),但我不确定问题在哪里。
使用Sinon spies/stubs测试异步函数是很困难的,因为(AFAIK)您无法让它在被调用时告诉您(它甚至可能永远不会被调用)。
在您的例子中,您假设PostModel。find()
将在下一个勾号中完成(根据您使用的process.nextTick()
),很可能不是这样,因此您正在检查您的间谍,而此时查询仍在运行,并且还没有调用任何间谍。
在我看来,您试图用一个测试来测试太多内容:PostModel。find()
、dbQuery()
和控制器。readAllPosts()
。我可能会在不同的测试中将它们分开,并将其余部分存根。
例如,如果你想检查你的控制器是否发送回正确的响应,或者它是否正确地处理错误,存根PostModel.find()
让它(同步地)调用回调,要么有错误,要么有正确的结果数组,并随后检查res.send/res.json
间谍。
另一个选择是不使用间谍,而是简单的回调。例如:
controller.readAllPosts(req, {
send : function(data) {
assert(data, ...);
done();
},
json : function(data) {
assert(data, ...);
done();
},
});
(或其变更)
然而,我不喜欢这样做,因为它会阻止您测试(以一种简单的方式)这些方法并没有被调用。
我试图理解西农图书馆的假、间谍、存根和模拟之间的区别,但无法清楚地理解。 有人能帮我了解一下吗?
问题内容: 我有内部类的课程,如下所示: 模仿测试如下所示:build.gradle: 测试: 第一次测试正在按预期方式工作。第二个永远不会被检测为“已调用”,尽管在日志中我看到的是。有什么问题吗?:) 谢谢! 问题答案: 怎么了? 好吧,这里的问题非常微妙,当您调用时,会在实例背后创建某种装饰器,以允许监视实例上的所有方法调用。因此,您可以检查给定方法被调用了多少次, 但是在装饰器 上 却 没有
所以我有一个调用https请求的方法。我已经成功地在其他测试中中断了调用,但是这个测试打败了我,因为它根本不起作用。 在我的beforeach中,我创建存根,在我的afterEach中,我执行存根还原 在测试中,我创建了四个存根调用。
Mockito——我知道间谍在对象上调用实际方法,而模拟在双对象上调用方法。此外,除非有代码气味,否则要避免间谍。然而,间谍是如何工作的?我应该在什么时候使用他们?它们与模拟有什么不同?
问题内容: 我有两个Redis客户端,在一个文件中,我有一个简单的脚本设置并删除了Redis密钥: 在第二个文件中,我有一个Redis客户端充当订户: 关键的“占位符”已设置,那么是否有充分的理由使我在“消息”处理程序中未获得任何输出? 问题答案: 您忘记了订阅用户客户端订阅特定的频道。此外,如果要监视所有事件,则需要使用基于模式的订阅。 您可能想要执行以下操作(未测试): 请参阅Redis文档和
我在两个无界流之间有一个简单的间隔连接。这适用于较小的工作负载,但对于较大的(正式生产环境),它不再有效。通过观察输出,我可以看到FlinkSQL作业仅在扫描整个主题(并因此读入内存?)后才触发/发出记录,但我希望作业在找到ingle匹配后立即触发记录。因为在我的正式生产环境中,作业无法承受将整个表读入内存。 我正在做的间隔连接与这里提供的示例非常相似:https://github.com/ver