[英]Test async.waterfall in node.js with sinon.js timers
我有以下功能,我希望測試它在其中大量使用async.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假定時器,我的斷言代碼仍然是先執行。 如果我使用一些嵌套的setImmediate()
調用它工作正常,但這是解決這個問題的最糟糕的解決方案。
你遺漏了很多東西,所以很難說它應該做什么。 老實說,這聽起來像是噪音,雖然這不是你的錯。
如果您實際上並不需要並行執行大量IO,那么這就是我的建議。 切換到ES2017和babel。 使用帶有@autobind的類或類似的語法:
class Test {
constructor(testB) {
this.testB = testB;
}
fuzz = async x => x+1;
async foo = (bar) => {
try {
const result = await this.testB.blah(bar);
return await this.fuzz(result);
} catch (e) {
console.error(e);
return null;
}
}
async fizz = (bars) => await Promise.all(bars.map(this.foo));
}
然后使用ava
進行測試。 這樣,你有一個干凈的方式( await
)來處理與循環和異步測試異步功能的基本流程,你的方法this
將始終指向您的實例。
好吧,根據以下問題我覺得這是舊版本中的一個錯誤: https : //github.com/caolan/async/issues/609
https://github.com/caolan/async/issues/106
雖然它們已經很老了,而且我使用的是較新的版本,但我剛剛更新了我的依賴項,它現在運行正常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.