我尝试查看具有类似错误的主题,但是无法将这些解决方案适合我的问题。
当我尝试运行以下测试(包括已测试的功能):
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 }
]
});
});
答案 0 :(得分:0)
您需要在return
的{{1}}块中添加if
,以便回调函数myFunc
仅被调用一次,实际上next
被调用主要测试案例中的回调:
done()
答案 1 :(得分:0)
@Ankif Agarwal的解决方案不是正确的解决方案,但确实为我指明了正确的方向。
forEach()方法没有短路,因此多次调用next()(Short circuit Array.forEach like calling break)。
我能够用以下两种方法之一解决此问题。
通过从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();
}
}
但是,这仍然使forEach()遍历所有元素。如果可能的话,最好将其短路并在发生设置错误的违规情况时立即将其断开,例如:
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);
}
}
希望将来有人可以使用它。