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

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.

当前回答

自定义错误类

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

例子

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

其他回答

你可以这样测试你的async函数:

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

'I should fail'字符串将匹配抛出的错误的任何部分。

我想在此基础上补充一点,说明您正在测试的函数必须抛出一个实际的Error对象抛出新的Error(…)。Jest似乎不能识别你是否抛出了一个像throw ' an error occurred!'这样的表达式。

如果你想测试一个async函数不抛出:

it('async function does not throw', async () => {
    await expect(hopefullyDoesntThrow()).resolves.not.toThrow();
});

不管返回的值是什么,上面的测试都将通过,即使是未定义的。

请记住,如果一个异步函数抛出一个错误,它实际上是作为一个承诺拒绝返回节点,而不是一个错误(这就是为什么如果你没有try/catch块,你会得到一个UnhandledPromiseRejectionWarning,与一个错误略有不同)。所以,就像其他人说的,这就是你使用either的原因:

.reject和.resolve方法,或者a 在测试中尝试/捕获块。

参考: https://jestjs.io/docs/asynchronous#asyncawait

为了能够创建许多测试条件,而不必每次都解析承诺,这也可以工作:

it('throws an error when it is not possible to create an user', async () => {
        const throwingFunction = () => createUser(createUserPayload)

        // This is what prevents the test to succeed when the promise is resolved and not rejected
        expect.assertions(3)

        await throwingFunction().catch(error => {
            expect(error).toBeInstanceOf(Error)
            expect(error.message).toMatch(new RegExp('Could not create user'))
            expect(error).toMatchObject({
                details: new RegExp('Invalid payload provided'),
            })
        })
    })

我一直在测试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
  });

这是建立在丽桑德罗的答案之上的。