使用 promise resolve/reject 进行单元测试猫鼬验证

Unit testing mongoose validation with promise resolve/reject

我正在努力寻找一种方法来对 mongoose 中的字段验证进行单元测试。我目前有以下测试:

it('should be invalid if googleId is empty', () => 
  testBook.googleId = '';
  const newBook = new Book(testBook);
  return newBook.validate().catch((err) => {
    should.exist(err.errors.googleId);
  });
});

此测试未按预期工作,因为如果我对 googleId 进行了正确验证,测试将通过,因为它将断言 err.errors.googleId 存在,但如果我没有googleId 的任何验证也将通过,因为 .catch() 永远不会被调用并且它假定测试通过。

我试过将 should.fail() 放在 .then() 中,但这样它总是以 .catch() 结束,但有不同的错误,如果没有验证,它将被捕获should.fail() 错误,如果有验证,它将捕获模型验证错误。

实现这种测试的最佳方法是什么?

非常感谢!

编辑: 我已经尝试使用 newBook.validate() 的回调并且它有效,但我从来没有对模型方法使用回调,我总是倾向于使用承诺,所以我应该在这种特殊情况下使用回调还是还有更好的方法使用承诺处理它?

您可以使用第二个参数,然后在第一个参数中放入一些东西,例如:

return newBook.validate().then(
    resp => throw new Error("Test failed this should not resolve"),
    err =>  should.exist(err.errors.googleId);
});

所以现在如果 newBook.validate() 没有被拒绝,测试就会失败。由于您没有使用 catch() ,因此您不会阻止它导致测试失败。如果承诺被拒绝,那么你的测试应该通过(假设它满足设定的条件)。这是有效的,因为与 catch() 不同,then() 的错误回调不会捕获 then() 中抛出的错误。当然,您可以在第一个抛出错误的回调中放入任何内容,例如 assert.fail() 或您的库中的任何内容。

有一个 chai-as-promised 插件,其中包含使 Promise 测试更像普通 chai expect/should 那样工作的助手。

.rejectedWith.rejected 处理错误的方式与常规 .throw.

大致相同
const chai = require('chai')
chai.should()
chai.use(require('chai-as-promised'))

it('should be invalid if googleId is empty', function(){
  testBook.googleId = ''
  const newBook = new Book(testBook)
  return newBook.validate()
     .should.be.rejectedWith('Validation Failed')
     .and.eventually.have.nested.property('errors.googleId')
});

如果您要加载任何其他插件,请确保最后加载该插件 chai plugins,否则事情会变得一团糟。