【问题标题】:Can you write async tests that expect toThrow?你能写出期望抛出的异步测试吗?
【发布时间】:2018-04-19 01:02:42
【问题描述】:

我正在编写一个异步测试,期望异步函数像这样抛出:

it("expects to have failed", async () => {
  let getBadResults = async () => {
    await failingAsyncTest()
  }
  expect(await getBadResults()).toThrow()
})

但是开玩笑只是失败了,而不是通过了测试:

 FAIL  src/failing-test.spec.js
  ● expects to have failed

    Failed: I should fail!

如果我将测试重写为如下所示:

expect(async () => {
  await failingAsyncTest()
}).toThrow()

我收到此错误,而不是通过测试:

expect(function).toThrow(undefined)

Expected the function to throw an error.
But it didn't throw anything.

【问题讨论】:

    标签: javascript jestjs


    【解决方案1】:

    你可以像这样测试你的异步函数:

    it('should test async errors', async () =>  {        
        await expect(failingAsyncTest())
        .rejects
        .toThrow('I should fail');
    });
    

    “我应该失败”字符串将匹配所抛出错误的任何部分。

    【讨论】:

    • 实际上有问题,记录的示例失败。 github.com/facebook/jest/issues/3601 有解决方法,包括 await expect(failingAsyncTest()).rejects.toHaveProperty('message', 'I should fail');
    • @Lisandro 此代码不起作用。是的,单元测试通过了,但不是因为failingAsyncTest 抛出了正确的错误。如果您更改 failingAsyncTest 的实现以抛出 错误的错误 而不是正确的错误,则更明显。 (使用 Jest 23.6)
    • @Tom 该解决方案从未声称与错误 Type 匹配。它清楚地说明了字符串匹配 de error Message。它工作得很好。最好的。
    • expect(promise).rejects.toMatch(error) 和 expect(promise).rejects.toThrow(error) 有什么区别。不应该拒绝解开实际错误吗?然后,这没有意义(或者对我来说没有意义)-> expect(error).toThrow(error)。这里有一个带有拒绝的 toMatch 示例:jestjs.io/docs/asynchronous#asyncawait
    【解决方案2】:

    我想补充一点,你正在测试的函数必须抛出一个实际的错误对象throw new Error(...)。如果你只是抛出一个像throw 'An error occurred!' 这样的表达式,Jest 似乎无法识别。

    【讨论】:

    • 你刚刚为我节省了大量时间。
    • 如果我们要保留throw 'an error',有什么解决方法吗?
    • 我正在包装应该在测试中抛出 try catch 的函数。然后在 catch 块中我可以做 expect(error).toMatchObject(expectedError) 但它看起来很狡猾
    【解决方案3】:
    await expect(async () => { 
        await someAsyncFunction(someParams); 
    }).rejects.toThrowError("Some error message");
    

    我们必须将代码包装在一个函数中以捕获错误。在这里,我们期望 someAsyncFunction 抛出的错误消息应该等于“一些错误消息”。我们也可以调用异常处理程序

    await expect(async () => { 
        await someAsyncFunction(someParams); 
    }).rejects.toThrowError(new InvalidArgumentError("Some error message"));
    

    阅读更多https://jestjs.io/docs/expect#tothrowerror

    【讨论】:

      【解决方案4】:

      我一直在测试 Firebase 云功能,这就是我想出的:

      test("It should test async on failing cloud functions calls", async () => {
          await expect(async ()=> {
              await failingCloudFunction(params)
          })
          .rejects
          .toThrow("Invalid type"); // This is the value for my specific error
        });
      

      这是建立在lisandro's answer之上的。

      【讨论】:

        【解决方案5】:

        自定义错误类

        rejects.toThrow 的使用对您不起作用。相反,您可以将rejects 方法与toBeInstanceOf 匹配器结合起来,以匹配已引发的自定义错误。

        示例

        it("should test async errors", async () => {
          await expect(asyncFunctionWithCustomError()).rejects.toBeInstanceOf(
            CustomError
          )
        })
        

        
        it("should test async errors", async () => {
          await expect(async () => {
            await asyncFunctionWithCustomError()
          }).rejects.toBeInstanceOf(CustomError)
        })
        

        【讨论】:

          猜你喜欢
          • 2020-11-24
          • 1970-01-01
          • 2012-09-29
          • 2018-10-30
          • 1970-01-01
          • 2017-12-06
          • 2017-10-31
          • 2023-02-08
          • 2011-05-07
          相关资源
          最近更新 更多