You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jest.js中如何在未按预期抛出错误时判定测试用例失败

问题场景

你正在为Feathers.js/Node.js API补充测试提升分支/函数覆盖率,测试框架选用Jest。当前某服务存在一个带取值约束的属性,对应校验逻辑暂未实现:

  • 合法取值范围:
const validValues = ["System", "Engineering", "Production"]
  • 非法取值示例:
const invalidValues = ["Some", "Invalid", "Value"]

预期逻辑为:传入合法值时API正常接收请求并返回有效响应;传入非法值时API直接拒绝请求。
你计划先编写测试用例,实现“API接收非法值(未抛出预期错误)时测试直接失败”的效果,倒逼校验逻辑补全,但当前编写的测试代码无法达到这个判定效果。
你当前的测试代码如下:

it("test service for invalid values", async () => {
    const invalidValues = ["Some", "Invalid", "Value"];

    invalidValues.map(async (invalidValue) => {
      await expect(async () => {
        await app.service("release-types").create({
          someProperty: "some Value"
          propertyWithValueConstraint: invalidValue,
        });
      }).rejects.toThrow();
    });
  });
原有代码的核心问题
  • 用Array.map遍历执行异步断言时,没有等待map返回的Promise数组执行完成。Jest会在测试函数同步代码执行完后直接结束用例,根本不会等内部的异步请求和断言执行,就算服务没抛错,测试也会误判为通过,出现假阳性结果。
  • expect的rejects断言写法冗余,不需要额外包裹一层async函数,直接传入返回Promise的服务调用即可。
  • 缺少合法值的对照用例,无法覆盖“接口无论传什么值都抛错”的反向异常场景。
正确实现方案

推荐用for...of循环逐个执行异步断言,保证Jest能等待所有校验逻辑执行完成,代码如下:

it("should reject requests with invalid property values", async () => {
  const invalidValues = ["Some", "Invalid", "Value"];
  // 用for...of替代map,逐个等待异步断言执行
  for (const invalidValue of invalidValues) {
    await expect(
      app.service("release-types").create({
        someProperty: "some Value",
        propertyWithValueConstraint: invalidValue,
      })
    ).rejects.toThrow();
  }
});

// 补充合法值对照用例,避免校验逻辑写死全量拦截
it("should accept requests with valid property values", async () => {
  const validValues = ["System", "Engineering", "Production"];
  for (const validValue of validValues) {
    await expect(
      app.service("release-types").create({
        someProperty: "some Value",
        propertyWithValueConstraint: validValue,
      })
    ).resolves.not.toThrow();
  }
});

如果你想并行执行所有非法值校验,也可以用Promise.all包裹map返回的Promise数组,效果一致:

it("test service for invalid values", async () => {
  const invalidValues = ["Some", "Invalid", "Value"];
  await Promise.all(
    invalidValues.map(async (invalidValue) => {
      await expect(
        app.service("release-types").create({
          someProperty: "some Value",
          propertyWithValueConstraint: invalidValue,
        })
      ).rejects.toThrow();
    })
  );
});
效果说明

只要校验逻辑没实现,服务接收非法值后没有抛出错误,rejects.toThrow()断言就会直接判定失败,完全符合你“校验逻辑缺失时测试挂掉”的需求。后续补全校验后,你还可以把toThrow()替换为更精准的断言,比如指定错误类型、匹配错误提示文本,进一步提升测试严谨性。

内容的提问来源于stack exchange,提问作者ix.trc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 12:09:13