【问题标题】:Expect a function to throw an exception in Jest期望函数在 Jest 中抛出异常
【发布时间】:2020-05-01 23:37:30
【问题描述】:

我有一个返回承诺的函数 (hostelService.book):return Promise.resolve(response); 我做了这个测试:

const action = async () => {
        await hostelService.book(id);
    };


  await expect(action).rejects.toThrow();

但我有这个错误:

 Matcher error: received value must be a promise

【问题讨论】:

  • 只有toThrow 调用提供的值。 rejects 要求它已经是一个promise,而不是一个返回一个promise的函数。我认为.rejects.toThrow() 根本没有意义;你可能想要expect(hostelService.book(id)).rejects.toEqual(someError)。见jestjs.io/docs/en/tutorial-async.html#rejects

标签: javascript node.js typescript jestjs


【解决方案1】:

Jest 抛出此错误Matcher error: received value must be a promise,因为在expect 中您只是传递函数引用。没有() - action 只是一个函数引用,它不会返回任何内容。

要解决此问题,您必须像 action() 一样在 expect 中调用函数,以便它返回 promise 对象。

第二部分,你必须抛出错误。 Promise.reject(new Error('some error')); 在拒绝中,因此 tothrow 条件可以完全填充。

示例:

function hostelService() {
   return Promise.reject(new Error('some error'));
}

const action = async () => {
   await hostelService();
};

it( "Should throw the error", async () => {
   await expect(action()).rejects.toThrow('some error');
});

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    看来你差不多了。我创建了一个代码沙盒,其中包含一个引发错误的函数和一个通过的测试。您可以在代码沙箱内的终端中使用npm run test 运行它。这是链接:

    https://codesandbox.io/s/musing-goodall-ssss4?fontsize=14&hidenavigation=1&theme=dark

    但基本上代码是这样的:

    const action = async () => {
      throw new Error("error!")
    }
    
    describe("func", () => {
      it("should fail", async () => {
        await expect(action()).rejects.toThrow()
      })
    })
    
    

    与您显示的代码的区别在于缺少action() 中的调用,可能是类型错误。我不知道这是一个错误还是不仅仅是代码,你只是想解释你想要什么。将来,为了更好地理解并帮助您未来的“助手”,您应该发布您的代码的 sn-p(或修改以避免属性问题)。

    【讨论】:

      【解决方案3】:

      您的测试失败,因为您正在等待承诺(因此,当您在其上调用 .rejects 时,它不再是 Promise)。如果您从最后一条语句中删除 await,它应该可以解决问题:

      const action = async () => {
        await hostelService.book(id);
      };
      
      expect(action()).rejects.toThrow();
      

      这是它背后的一些基本原理。 async 自动将您的返回类型包装到 Promise 中。但是,当您调用 await 时,它会同步“解包”给定 Promise 的值,因此它不能在结果上调用 .rejects(除非您将 Promise 包装到另一个 Promise 中)。

      我写了a small example 来说明我的意思。

      【讨论】:

        【解决方案4】:

        很遗憾,您无法直接使用 toThrow() 测试拒绝。拒绝它自己是一个错误对象,因此您可以测试是否相等。

        test('', () => {
          // dont forget to call the action. 
          await expect(action()).rejects.toEqual(new Error())
        });
        

        您可以在这里找到更多解决方法https://github.com/facebook/jest/issues/1700

        【讨论】:

          【解决方案5】:

          这里的 action 就是函数,你不是从期望中调用它。我还从最后一行删除了等待

          试试这个解决方案

          const action = async () => {
            await hostelService.book(id);
          };
          expect(action()).rejects.toThrow();
          

          【讨论】:

          • 您最后的评论不正确。您不应从 expect(...).rejects.toThrow('some message'); 语句中删除 await。它可能会或可能不会起作用,具体取决于它是否是测试的最后一条语句等,但您实际上所做的是在异步代码仍在执行的情况下完成测试,这可能意味着您将在测试中调用拆解代码。在测试中始终等待异步调用。
          猜你喜欢
          • 2017-11-27
          • 2017-12-06
          • 1970-01-01
          • 2023-02-08
          • 2019-08-16
          • 2022-01-03
          • 1970-01-01
          • 2020-04-06
          • 1970-01-01
          相关资源
          最近更新 更多