【问题标题】:How to test for mongoose model validation errors with Jest using async/await?如何使用 async/await 使用 Jest 测试猫鼬模型验证错误?
【发布时间】:2020-02-04 23:06:02
【问题描述】:

我正在尝试使用 Jest 测试一个简单的模型验证。 模型如下:

const { Schema, model } = require('mongoose')
const { isEmail, isAlphanumeric, isNumeric, isAlpha } = require('validator')


const userSchema = new Schema({
  name: {
    type: String,
    required: true
  },
  email: {
    type: String,
    validate(v) {
      return isEmail(v)
    }
  }
})

const User = model('User', userSchema)

然后,在我的测试文件中,我有以下设置:

const User = require("../models/user");

const invalidUser = {
  name: "David",
  email: "david@invalid"
};

const validUser = {
  name: "David",
  email: "david@example.com"
};

现在,当我尝试使用回调运行测试时,我得到了想要的结果(错误是 null):

test("Should not validate user without valid email", done => {
  const user = new User(invalidUser);
  user.validate(err => {
    expect(err).not.toBeNull();
    done();
  });
});

但是,当我将该测试重构为使用 async/await 时,它每次都会通过,即使我将 invalidUser 更改为有效的电子邮件(这应该会导致测试失败):

test("ASYNC Should not validate user without valid email", async () => {
  try {
    const user = new User(invalidUser);
    await user.validate();
  } catch (e) {
    expect(e).not.toBeNull();
  }
});

我的猜测是e 没有正确填充来自validate() 的错误,但这是为什么呢? 谢谢!

【问题讨论】:

    标签: javascript node.js unit-testing async-await jestjs


    【解决方案1】:

    您的异步版本不正确,因为它总是会成功完成。考虑到:

    • 当您使用invalidUser 时,将调用catch() 块并显示您预期的错误,因此您将检查not.toBeNull(),一切都会好起来的。
    • 当您使用 validUser 时,user.validate() 承诺将被正确解析,因此您的 catch 块将不会被执行,您的测试用例也将成功完成。

    因此,您需要一种不同的方法,以确保在成功解决 validate() 承诺时拒绝您的测试:

    test("ASYNC Should not validate user without valid email", async () => {
      let error = null;
    
      try {
        const user = new User(invalidUser);
        await user.validate();
      } catch (e) {
        error = e;
      }
    
      expect(error).not.toBeNull();
    });
    
    

    【讨论】:

      【解决方案2】:

      更正确的方法可能是使用 jest 的 .rejects.toThrow(),如 this。在你的情况下:

      test("ASYNC Should not validate user without valid email", async () => {
          const user = new User(invalidUser);
          await expect(user.validate()).rejects.toThrow();
      });
      

      如果您需要特定的错误消息,可以通过将其添加为如下参数来测试它:.toThrow('error message goes here')。在jest docs 中了解更多信息。

      【讨论】:

        猜你喜欢
        • 2019-08-04
        • 2019-04-25
        • 2021-06-18
        • 2019-01-19
        • 2020-10-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-29
        相关资源
        最近更新 更多