[英]Failing test - Mocha's done() called multiple times
I've tried looking at topics with a similar error but could not fit those solutions into the context of my issue.我尝试查看具有类似错误的主题,但无法将这些解决方案融入我的问题的上下文中。
When I try to run the the following test (function included that is tested):当我尝试运行以下测试时(包含的功能已测试):
function myFunc(next, obj) {
const pairs = {};
obj.listing.forEach((element) => {
if (element.x in pairs && pairs[element.x] !== element.y) {
const err = new Error('This was not ok');
next(err);
} else {
pairs[element.x] = element.y;
}
});
next();
}
it('should fail as 9 has been changed to 5 in the second object of the listing', function (done) {
const callback = (err) => {
if (err && err instanceof Error && err.message === 'This was not ok') {
// test passed, called with an Error arg
done();
} else {
// force fail the test, the `err` is not what we expect it to be
done(new Error('Assertion failed'));
}
}
myFunc(callback, {
"listing": [
{ "x": 5, "y": 9 },
{ "x": 5, "y": 11 }
]
});
});
I get this error:我收到此错误: What is the cause of this and how can I fix it?这是什么原因,我该如何解决?
You need to add a return
in the if
block of your myFunc
so that the callback function next
is called only once and indeed the done()
callback in the main test case:您需要在myFunc
的if
块中添加一个return
,以便只调用一次回调next
并且确实在主测试用例中调用done()
回调:
function myFunc(next, obj) {
const pairs = {};
obj.listing.forEach((element) => {
if (element.x in pairs && pairs[element.x] !== element.y) {
const err = new Error('This was not ok');
return next(err);
} else {
pairs[element.x] = element.y;
}
});
next();
}
@Ankif Agarwal's solution was not the correct one but it did point me in the right direction. @Ankif Agarwal 的解决方案不是正确的,但它确实为我指明了正确的方向。
The forEach() method is not short circuited and therefor makes a call to next() more than once ( Short circuit Array.forEach like calling break ). forEach() 方法没有短路,因此多次调用 next() ( 短路 Array.forEach 就像调用 break 一样)。
I was able to solve this in one of two way's.我能够以两种方式之一解决这个问题。
By extracting the call to next() from the forEach() logic:通过从 forEach() 逻辑中提取对 next() 的调用:
function myFunc(next, obj) {
const pairs = {};
let err = null;
obj.listing.forEach((element) => {
if (element.x in pairs && pairs[element.x] !== element.y) {
err = new Error('This was not ok');
} else {
pairs[element.x] = element.y;
}
});
if (err !== null) {
next(err);
} else {
next();
}
}
However this still makes the forEach() run through all element.然而,这仍然使 forEach() 贯穿所有元素。 If possible it seems better to short circuit it and break out of it soon as a violation occurs that sets the error, like so:如果可能的话,最好将其短路并在发生设置错误的违规行为时立即将其断开,如下所示:
function myFunc(next, obj) {
const pairs = {};
const BreakException = {};
let err = null;
try {
obj.listing.forEach((element) => {
if (element.x in pairs && pairs[element.x] !== element.y) {
err = new Error('This was not ok');
throw BreakException;
} else {
pairs[element.x] = element.y;
}
});
next();
} catch (e) {
if (e !== BreakException) throw e;
next(err);
}
}
Hopefully someone can use this in the future.希望将来有人可以使用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.