Jest: async/await toThrow 不起作用

创建于 2016-09-15  ·  21评论  ·  资料来源: facebook/jest

下一个测试

async function check() {
  throw new Error('Test');
}

expect(async () => 
  await check()
).toThrow();

会失败并且不能正确捕获错误(我使用的是最新版本的笑话)

最有用的评论

代替

expect(async () => await check()).toThrow()
// Jest error: "Expected the function to throw an error. But it didn't throw anything."

这有效:

expect(check()).rejects.toEqual(new Error('Test'))

是的,语法很尴尬......

所有21条评论

是的,目前不支持。 见https://github.com/facebook/jest/issues/1377

代替

expect(async () => await check()).toThrow()
// Jest error: "Expected the function to throw an error. But it didn't throw anything."

这有效:

expect(check()).rejects.toEqual(new Error('Test'))

是的,语法很尴尬......

你也可以写:

let error;
try {
  await check();
} catch (e) {
  error = e;
}
expect(error).toEqual(new Error('Test'));

以下对我也有用:

async function check() {
  throw new Error('Test');
}

expect(check()).rejects.toEqual(new Error('Test'))

请参阅: https :

添加到解决方法列表中。
如果你喜欢我想捕捉特定的错误类型,而不关心消息:

async function check() {
  throw new SomeSpecificError('Whatever');
}

await check()
  .then(() => {
    throw new Error('Should go to .catch, not enter .then');
  })
  .catch((err) => {
    expect(err).toBeInstanceOf(SomeSpecificError);
  });
await expect(check).rejects.toThrow(SomeSpecificError);

也应该工作

await expect(check).rejects.toThrow(/DUPLICATES_DETECTED/);

是我做的。

async function check() {
  throw new Error("Test");
}
await expect(check).rejects.toThrow(Error);
expect(received).rejects.toThrow()

received value must be a Promise.
Received:
 function: [Function check]

你需要调用它来给它实际的承诺

async function check() {
  throw new Error("Test");
}
await expect(check()).rejects.toThrow(Error);

也应该工作

it(`some test`, async () => {
  async function check() {
    try {
      return Promise.reject(await asyncMethod());
    } catch (error) {
      throw new Error("test");
    }
  }
  await expect(check()).rejects.toThrow(Error);
});

能行得通

版本

  • 笑话: 23.4.2
  • ts-jest: 23.1.2

我知道它需要一个承诺,但你提供的情况不是:)

你好 ! 我可能做错了什么,但我仍然遇到异步调用中的自定义错误问题。 考虑以下:

class CustomErrorType {}
// ...
test('check throws custom error', async () => {            
    async function check() {
        throw new CustomErrorType();
    }
    await expect(check()).rejects.toThrow(CustomErrorType);
});

然后测试失败,输出如下:

期望函数抛出类型错误:
“自定义错误类型”
但它什么也没扔。

所以测试失败了——虽然当抛出的类是Error时它工作得很好。 当我尝试扩展Error
```javascript
class CustomErrorType 扩展 Error {}
````

那么错误是

期望函数抛出类型错误:
“自定义错误类型”
相反,它抛出:
错误

关于该样本有什么问题的任何线索? 我正在使用笑话 23.4.2。

@Marchelune当您编写class CustomErrorType extends Error {}您实际上还没有定义一个新类。 如果你给 CustomErrorType 一个主体,即使只是一个只调用 super() 的构造函数,它也会起作用。

万一有人抛出任何与实例错误类不同的东西,并努力使用来自该线程的建议(就像我所做的那样)。
toThrow()将检查抛出的值是 Error 类的实例,如果不是 - 将不会检测到抛出。 从文档和常识来看,这并不明显。
这将失败,即使它明确抛出:

async function f() {throw 'aa'}
const res = await expect(f()).rejects.toThrow()`

但这会起作用(不确定是否有更好的方法):

async function f() {throw 'aa'}
const res = await expect(f()).rejects.toBeTruthy()`

@Karabur错字toBeThruthy应该是toBeTruthy

这是一个显式测试,可确保如果它不抛出并匹配特定错误,它肯定会中断。

yourCoolAsyncMethod('yeah it is')
    .then(ok => { // Presumes not a Promise<void>
        expect(ok).toBeUndefined();
        done();
    })
    .catch(bad => {
        expect(bad).toBeDefined();
        expect(bad).toMatchInlineSnapshot(
            `Specifically serious error!`
        );

        done();
    });

嗨@SimenB。
如果我有这个并且它正在工作。

async function check() {
    // do something
}
await expect(check()).rejects.toThrow(InternalServerErrorException);

InternalServerErrorException 与对象一起抛出....

我怎样才能在抛出的错误上断言属性? 例如:

  • 异常信息 = '错误'
  • 异常状态 = '500'

这是一个显式测试,可确保如果它不抛出并匹配特定错误,它肯定会中断。

yourCoolAsyncMethod('yeah it is')
    .then(ok => {
        expect(ok).toBeUndefined();
        done();
    })
    .catch(bad => {
        expect(bad).toBeDefined();
        expect(bad).toMatchInlineSnapshot(
            `Specifically serious error!`
        );

        done();
    });

问题是如果代码从来没有错误,你的测试就会通过。

所以这个测试不会真正提供太多价值,因为它的预期结果会根据它测试的代码是否有错误而有所不同。

测试应该有负流或正流,我们应该只测试需要测试的内容。 这种随机性并不是最大的。

嘿@David-Tennant 🖐

感谢您指出这一点。 当时我正在研究Promise<notVoid>方法。 我意识到我没有分享对Promise<void>也有效的通用解决方案。 我用评论更新了我的答案,说我做了假设。 我同意你关于流程的看法。

谢谢💨

你好@futuredayv 👋

嘿@David-Tennant 🖐

感谢您指出这一点。 当时我正在研究Promise<notVoid>方法。 我意识到我没有分享对Promise<void>也有效的通用解决方案。 我用评论更新了我的答案,说我做了假设。 我同意你关于流程的看法。

谢谢💨

问题是,如果测试确实返回 void,您的测试仍然会通过。 哪个应该是错误?
调用done()表示“我的测试已以预期的方式通过,我已准备好进行下一次测试”

yourCoolAsyncMethod('yeah it is')
     // -- Lets say your method does not throw, and returns void instead
    .then(ok => { // Presumes not a Promise<void>
        expect(ok).toBeUndefined(); // -- At this point if it was void, this would pass
        done(); // -- Then your test would end and the catch would not be reached
        // -- Now you have unknown behavior passing a test where it's suppose to catch a fail
    })
    .catch(bad => {
        // -- This block does not run because done() is called above
        expect(bad).toBeDefined();
        expect(bad).toMatchInlineSnapshot(
            `Specifically serious error!`
        );

        done();
    });

不确定您的用例的解决方案是什么。 但是我首先不会在then调用done()或者在“then”中抛出错误以确保测试失败,

yourCoolAsyncMethod('yeah it is')
    .then(ok => throw new Error("This block of code should not be reached")
    .catch(bad => {
        expect(bad).toBeDefined();
        expect(bad).toMatchInlineSnapshot(
            `Specifically serious error!`
        );

        done();
    });

万一有人抛出任何与实例错误类不同的东西,并努力使用来自该线程的建议(就像我所做的那样)。
toThrow()将检查抛出的值是 Error 类的实例,如果不是 - 将不会检测到抛出。 从文档和常识来看,这并不明显。
这将失败,即使它明确抛出:

async function f() {throw 'aa'}
const res = await expect(f()).rejects.toThrow()`

但这会起作用(不确定是否有更好的方法):

async function f() {throw 'aa'}
const res = await expect(f()).rejects.toBeTruthy()`

更好的方法是使用toBeDefined()而不是toBeTruthy()
async function f() {throw 'aa'} const res = await expect(f()).rejects.toBeTruthy()`

此页面是否有帮助?
0 / 5 - 0 等级