【问题标题】:How to mock non-async method for throwing an exception with Jest?如何模拟非异步方法以使用 Jest 引发异常?
【发布时间】:2019-07-31 07:33:28
【问题描述】:

这是我在 TypeScript 中的代码片段:

let myService: MyService;
let myController: MyController;

beforeAll(async function () {
    myService = new MyService(null);
    myController = new MyController(myService);
});

it("should fail due to any 'MyService' error", () => {
    jest.spyOn(myService, 'create').mockImplementation(() => {
        throw new Error(); // ! the test fails here
    });
    expect(myController.create(data)).toThrowError(Error);
});

MyControllercreate 方法不是异步的,MyService 也不是:两者都只是常规方法。现在,当我尝试运行此测试时,它在引发异常的模拟方法的行上失败:throw new Error() 并且只有当我将 create 方法调用与 try/catch 包装在一起时它才能正常工作:

try {
    expect(myController.create(data)).toThrowError(Error);
}
catch { }

我觉得这很奇怪。如果不按设计包装在 try/catch 中,它不应该工作吗?

【问题讨论】:

    标签: javascript testing jestjs ts-jest


    【解决方案1】:

    你只需要一点零钱。


    来自.toThrowError doc

    使用.toThrowError 测试函数在被调用时是否抛出。


    您正在传递 调用的结果 myController.create(data)

    您需要传递一个在调用时抛出的函数,在这种情况下:

    () => { myController.create(data); }
    

    将您的 expect 行更改为:

    expect(() => { myController.create(data); }).toThrowError(Error);  // SUCCESS
    

    ...它应该可以工作。

    【讨论】:

    • 所以,如果我们传递一个异步函数,这实际上意味着我们传递了一个由 Jest 管理的 Promise 包装器,这就是为什么我们不再需要将它包装在另一个函数中的原因在这种情况下(使用同步方法)?
    • @Sergey 是的,测试一个async 函数是否抛出一个Error 实际上只是测试它是否返回一个Promise 拒绝Error。更多详情请见this answer
    猜你喜欢
    • 1970-01-01
    • 2011-11-20
    • 2015-03-08
    • 2014-02-15
    • 2021-08-11
    • 1970-01-01
    • 2019-01-23
    • 2017-06-03
    • 1970-01-01
    相关资源
    最近更新 更多