2016-09-16 3 views
1

У меня есть следующие функции, которые я хотел бы быть проверены, которые используют async.js сильно в нем:Тест async.waterfall в Node.js с 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() и заставить его выполнить свой обратный вызов, потому что я останусь с ключевыми ветвями кода untested (Внутренние сделанные обратные вызовы async.each() и вторым async.waterfall(). Я попытался использовать синус поддельные таймеры и используются this.clock.tick(0); после вызова функции MyClass.prototype.pipeline() следующим образом:.

var obj = new MyClass(); 
obj.pipeline(5, 3); 
this.clock.tick(0); 
/* assertions */ 
... 

Но даже утверждения части выполняемых до того, как сделано функция вызывается я попытался углубиться в код библиотеки асинхронной чтобы увидеть, как это называет его выполненными функциями, это слишком большая головная боль, и я не мог понять, почему даже выполненные обратные вызовы откладываются и с тайными поддельными таймерами мой код подтверждения все еще выполняется f рвые. Если я использую некоторые вложенные вызовы setImmediate(), это работает отлично, но это худшее решение этой проблемы.

+0

Для чего нужен «.bind»? Это ваш фактический код или вы сокращаете что-то для этого вопроса? – clay

+0

@clay Я использую bind для вызова, чтобы сделать контекст самими экземплярами. Это код, удаленный из нерелевантных частей, везде, где вы видите '...' - нерелевантные части. также все имена являются фиктивными (a, b, c, d, e, f, arg1, arg2 и т. д.) – Jorayen

ответ

0

Вы оставили много вещей, поэтому трудно сказать, что это должно делать. В основном, если честно, это выглядит как шум для меня, хотя это не твоя вина.

Если вам не нужно делать много ввода-вывода параллельно, то вот что я предлагаю. Переключитесь на 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 всегда будут указывать на ваши экземпляры.

+0

К сожалению, я использую много ввода-вывода, и переключение на Babel теперь слишком много работы прямо сейчас, что Я не могу позволить себе прямо сейчас – Jorayen

+0

Хорошо, просто для того, чтобы уточнить, я имел в виду I/O параллельно, потому что казалось, что вы пытались сделать один ввод-вывод одновременно, а не одновременно. –

+0

О, я вижу, у вас есть async.each, который является параллельной частью. Я бы сделал его отдельной функцией с попыткой уловить внутри Promise.all. Во всяком случае, возможно, по линии, которую вы можете исследовать, когда у вас есть время для babel и т. Д. Удачи. –

0

Хорошо, это была ошибка в старой версии по следующим вопросам, которые я предполагаю: https://github.com/caolan/async/issues/609
https://github.com/caolan/async/issues/106

Хотя они довольно старый, и я использовал более новую версию, я только что обновил свой и теперь он работает нормально.

Смежные вопросы