我已经被测试了以下的功能,我想这在它大量使用async.js:测试async.waterfall与sinon.js定时器
MyClass.prototype.pipeline = function(arg1, arg2) {
...
async.waterfall([
async.apply(self.a.f.bind(self.a), arg1, arg2),
function(data, callback) {
async.each(data, function(d, callback) {
async.waterfall([
async.apply(self.b.f.bind(self.b), d),
self.c.f.bind(self.c),
self.d.f.bind(self.d),
self.e.f.bind(self.f)
], function(err, results) {
if (err) {
...
}
callback();
});
}, function(err) {
callback(err, data);
});
}
], function (err, result) {
...
});
};
现在我知道我可以分离在这里分隔函数的插图,但它是一个简化操作的管道,在前一个完成之后将数据从另一个传递到另一个,因此我希望将它保持为这样,例如将函数function(data, callback) {...}
与诸如BCDEpipeline之类的名称分开。 无论如何,我的问题是,我做了一些基于第一个async.waterfall()
完成函数完成回调的断言,问题是它后来被调用(延迟)即使我扼杀了a,b,c,d和e函数已经做出他们立即产生下一个回调。请注意,我不能只存根async.waterfall()
,并使其产生完成回调,因为我将留下未经测试的代码的关键分支(async.each()
和第二个async.waterfall()
内部完成回调 我试图使用sinon假定时器和使用this.clock.tick(0);
调用像这样的MyClass.prototype.pipeline()
功能后:
var obj = new MyClass();
obj.pipeline(5, 3);
this.clock.tick(0);
/* assertions */
...
但即使是这样被调用的任何完成函数之前被执行的部分断言我试图挖掘到异步库代码怎么看呢调用它的完成函数是令人头痛的事情,我无法弄清楚为什么即使完成的回调调用被推迟,并且用sinon假定时器,我的断言代码仍然执行f IRST。 如果我使用一些嵌套的setImmediate()
调用它可以正常工作,但这是这个问题最糟糕的解决方案。
什么是'.bind'?这是你的实际代码还是你缩短了这个问题的东西? – clay
@clay我使用bind来调用使上下文成为实例本身,这是从不相关的部分中剥离出来的代码,无论您看到什么,......都是不相关的部分。所有的名字都是虚构的(a,b,c,d,e,f,arg1,arg2等)。 – Jorayen