如何检查多个 chai-http 请求何时真正在块之前的 mocha 中完成?
How do I check when multiple chai-http requests are really done in a mocha before block?
我在一组 mocha 单元测试中使用了一个 before 块,并在其中迭代了一组调用以从 REST API 获取信息。我正在使用 chai-http 来执行此操作。然而,我 运行 遇到了 done()
方法在我提出的一系列 n 请求完成之前被调用的问题。在结束块中调用 done 会导致多次 done()
调用,但放在块外意味着它在我真正完成之前被调用!这是前块的示例:
var flags = [];
var groups = [];
// This functions correctly 1 done() called at the end
before(function(done) {
chai.request(server)
.get('/groups')
.end(function(err, res){
groups = JSON.parse(res.text);
done();
});
});
before(function(done) {
groups.forEach(function(rec) {
chai.request(server)
.get('/groups/' + rec.KEYWORD_GROUP_ID + '/groupflags')
.end(function(res, err) {
Array.prototype.push.apply(flags, JSON.parse(res.text));
// A done() here gets called n times
});
// But here it's called before the requests all end
done();
});
有没有一种方法可以检测所有这些请求何时完成,然后我可以调用一个 done()
来确保我的测试只在正确的上下文设置下执行?
你可以试试 async.whilst()
。计数到 groups.length,然后在回调中点击 done()
。 Link 到函数文档:(http://caolan.github.io/async/docs.html#whilst)
类似...
let counter = 0;
async.whilst(
() => {
// Test if we have processed all records
return counter < groups.length;
},
(callback) => {
let rec = groups[counter++]; // Sorry Douglas
chai.request(server)
.get('/groups/' + rec.KEYWORD_GROUP_ID + '/groupflags')
.end(function (res, err) {
Array.prototype.push.apply(flags, JSON.parse(res.text));
callback(null, counter);
});
},
(err) => {
assert(!err, err);
done();
}
);
正如 Alex 所要求的,这是我最初的解决方案:
before('delete keywords in a group', function(done) {
var count = 0;
var length = groups.length;
if (length === 0) {done();}
groups.forEach(function (rec) {
chai.request(server)
.delete('/keywords/' + rec.id)
.end(function (err, res) {
if (err) {
console.error('Delete keywords err: ' + err.message);
this.skip();
} else {
count++;
if (count === length) {done();}
}
});
});
});
这似乎可行,但我认为对于任何更复杂的情况(例如级联样式删除),异步库提供了更优雅和可靠的解决方案。因此它更适合一般情况。
我在一组 mocha 单元测试中使用了一个 before 块,并在其中迭代了一组调用以从 REST API 获取信息。我正在使用 chai-http 来执行此操作。然而,我 运行 遇到了 done()
方法在我提出的一系列 n 请求完成之前被调用的问题。在结束块中调用 done 会导致多次 done()
调用,但放在块外意味着它在我真正完成之前被调用!这是前块的示例:
var flags = [];
var groups = [];
// This functions correctly 1 done() called at the end
before(function(done) {
chai.request(server)
.get('/groups')
.end(function(err, res){
groups = JSON.parse(res.text);
done();
});
});
before(function(done) {
groups.forEach(function(rec) {
chai.request(server)
.get('/groups/' + rec.KEYWORD_GROUP_ID + '/groupflags')
.end(function(res, err) {
Array.prototype.push.apply(flags, JSON.parse(res.text));
// A done() here gets called n times
});
// But here it's called before the requests all end
done();
});
有没有一种方法可以检测所有这些请求何时完成,然后我可以调用一个 done()
来确保我的测试只在正确的上下文设置下执行?
你可以试试 async.whilst()
。计数到 groups.length,然后在回调中点击 done()
。 Link 到函数文档:(http://caolan.github.io/async/docs.html#whilst)
类似...
let counter = 0;
async.whilst(
() => {
// Test if we have processed all records
return counter < groups.length;
},
(callback) => {
let rec = groups[counter++]; // Sorry Douglas
chai.request(server)
.get('/groups/' + rec.KEYWORD_GROUP_ID + '/groupflags')
.end(function (res, err) {
Array.prototype.push.apply(flags, JSON.parse(res.text));
callback(null, counter);
});
},
(err) => {
assert(!err, err);
done();
}
);
正如 Alex 所要求的,这是我最初的解决方案:
before('delete keywords in a group', function(done) {
var count = 0;
var length = groups.length;
if (length === 0) {done();}
groups.forEach(function (rec) {
chai.request(server)
.delete('/keywords/' + rec.id)
.end(function (err, res) {
if (err) {
console.error('Delete keywords err: ' + err.message);
this.skip();
} else {
count++;
if (count === length) {done();}
}
});
});
});
这似乎可行,但我认为对于任何更复杂的情况(例如级联样式删除),异步库提供了更优雅和可靠的解决方案。因此它更适合一般情况。