簡體   English   中英

使用sinon.js計時器測試node.js中的async.waterfall

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM