gpt4 book ai didi

javascript - 使用 sinon.js 计时器在 node.js 中测试 async.waterfall

转载 作者:行者123 更新时间:2023-11-28 05:33:20 24 4
gpt4 key购买 nike

我希望测试以下函数,该函数大量使用 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) {
...
});
};

现在我知道我可以将这里发生的很多事情分开来分离函数,但它是一个在前一个完成后相互传递数据的简化操作的管道,所以我希望保持这样例如,使用 BCDEpipeline 之类的名称分隔函数 function(data,callback) {...}。不管怎样,我的问题是我根据第一个 async.waterfall() 完成函数的完成回调做了一些断言,问题是它稍后会被调用(延迟),即使我 stub 了 a, b, c、d 和 e 已经起作用并使其立即产生下一个回调。请注意,我不能只是 stub async.waterfall() 并使其产生完成回调,因为我将留下未经测试的代码的关键分支( 的内部完成回调async.each() 和第二个 async.waterfall()。我尝试使用 sinon 假定时器,并在调用 MyClass.prototype.pipeline() 函数后使用 this.clock.tick(0); ,如下所示:

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 将始终指向您的实例。

关于javascript - 使用 sinon.js 计时器在 node.js 中测试 async.waterfall,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39536100/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com