测试失败-多次调用Mocha的done()

时间:2019-10-31 07:36:26

标签: javascript unit-testing callback mocha

我尝试查看具有类似错误的主题,但是无法将这些解决方案适合我的问题。

当我尝试运行以下测试(包括已测试的功能):

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 }
    ]
  });
});

我收到此错误: enter image description here 是什么原因造成的,我该如何解决?

2 个答案:

答案 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);
  }
}

希望将来有人可以使用它。