【发布时间】:2017-01-30 18:42:31
【问题描述】:
我有一个函数,它计算一些东西,通过回调通知用户一些事件:
function returnAndCallback(callback) {
callback(5); // not always invoked
return 3;
}
使用 Mocha 和 Should.js,我编写了这个测试:
describe('mixing sync and async code', function() {
it('should test callback AND return value', function(done) {
returnAndCallback(function(value) {
value.should.be.eql(5);
done();
}).should.be.eql(4);
});
});
这会成功,因为测试在调用done() 时结束。看来,我可以编写一个同步测试并检查返回值,也可以编写一个异步测试并检查回调。
不能像这样使用同步测试:
describe('mixing sync and async code', function() {
it('should test callback AND return value', function() {
returnAndCallback(function(value) {
should.be.eql('difficult to get result');
}).should.be.eql(3);
});
});
... 因为我想断言回调被调用。如果从不调用回调,则此测试将成功。
如何测试回调是否使用正确的值和返回正确的值?
复制测试是我看到的唯一选择。
编辑:我注意到,我在这里错误地使用了异步一词。回调只是将可选操作注入到函数中的一种方式,该函数可以转换对象。所有代码都是同步的,但控制流有时会分支到回调中,我希望能够识别这一点。
这是另一种可能的测试方法:
describe('mixing sync and async code', function() {
it('should test callback AND return value', function() {
let callbackValue;
returnAndCallback(function(value) {
callbackValue = value;
}).should.be.eql(3);
callbackValue.should.be.eql(5);
});
});
但由于额外的变量,仍然不够优雅。
【问题讨论】:
-
我并不是要听起来很迂腐,但您的功能似乎是错误的。如果你有一个回调,那就是你返回的。为什么有时会有回调而有时会返回?
-
具体用例是一个验证器/检查器,它获取一个对象,检查它并可能更改一些字段。可以给一个回调,它报告所有的变化。最后返回选中的对象。
-
而在实践中,你如何使用这样的功能?
-
我使用 Socket.IO 并从大量不同的客户端实现中获取事件消息对象。我希望在处理这些消息时尽可能强大。有些只是缺少一个我可以用默认值填充的字段,但我仍然想通知客户端(用于调试),所以我发送了一个警告事件 - 这将在回调中发出。如果确实有问题,客户端会收到一个错误事件(当我想知道为什么 gps 位置搞砸时,这将帮助我更快地发现错字。我给出了一个 latutide,但 Chrome 默默地失败了)。
-
等效地,我可以返回一个对象
{ result: ..., warns: [ ... ], errors: [ ... ] },但如果我只能执行msg.gps = validate(msg.gps, reportError, reportWarn),它似乎并不那么优雅,其中report*函数是可选的或可选的无操作。跨度>
标签: javascript node.js unit-testing mocha.js