У меня есть следующие функции, которые я хотел бы быть проверены, которые используют 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()
, это работает отлично, но это худшее решение этой проблемы.
Для чего нужен «.bind»? Это ваш фактический код или вы сокращаете что-то для этого вопроса? – clay
@clay Я использую bind для вызова, чтобы сделать контекст самими экземплярами. Это код, удаленный из нерелевантных частей, везде, где вы видите '...' - нерелевантные части. также все имена являются фиктивными (a, b, c, d, e, f, arg1, arg2 и т. д.) – Jorayen