如何使用Jest测试catch语句中是否重新抛出错误



我有一个函数返回promise,但我想测试它是否定义了catch,然后再测试它是否重新抛出错误。

这是一个非常做作的例子,但它是表明这个问题的最清晰的方式。在我的实际代码中,我调用了一个被嘲笑为失败的函数(与本例中的手动拒绝相比(,并且我在catch语句中有额外的日志记录,这解释了错误的重新抛出。

const foo = () => {
return new Promise((resolve, reject) => {
reject(new Error('reject')); // manually rejecting to mimic actual code...
}).catch(error => {
// do some additional logging...
throw error;
});
};
it('should catch and re-throw error', () => {
// Received function did not throw
// and
// Unhandled promise rejection
expect(() => foo()).toThrow();
// Test passes, even when `throw error` is commented out with false positive
expect(foo()).rejects.toThrow();
});

我可以成功地检查日志记录函数是否被调用,但不知道如何确保在调用后重新抛出错误。

工作更新:(

感谢@skyboyer&@Bergi让我对这个问题有了一点不同的思考,并让我了解了的一些细节

下面是显示日志记录功能的更新代码,以及我确定的更新测试

导致这种情况的问题是

  • 无法测试由于重新抛出错误而调用的logging
  • 无法测试正在重新引发的错误的值

抓住被拒绝的承诺让我两者兼而有之。

我本来打算在rejects.toEqual考试中离开的,但现在看来是多余的。。。

对任何反馈感兴趣!再次感谢!

// myModule.js
export const logging = () => {};
export const bar = () => new Promise(resolve => {});
export const foo = () => {
return bar().catch(error => {
logging();
throw error;
});
};
describe('myModule', () => {
let fooReturn;
beforeEach(() => {
jest.clearAllMocks();
jest.spyOn(myModule, 'bar').mockImplementation(() => {
return Promise.reject({ error: 'bar error' });
});
jest.spyOn(myModule, 'logging').mockImplementation(() => {});
fooReturn = myModule.foo();
});
it('should catch and re-throw error', () => {
expect.assertions(1);
fooReturn.catch(result => expect(result).toEqual({ error: 'bar error' }));
// removed since the above test covers that the promise was rejected
// return fooReturn.rejects.toEqual(expect.anything());
});
it('should call the loggin method', async () => {
expect.assertions(1);
// prevents UnhandledPromiseRejectionWarning
fooReturn.catch(() => {});
expect(myModule.logging).toBeCalled();
});
});

您错过了return

https://jestjs.io/docs/asynchronous#resolves--拒绝

请确保返回断言——如果省略此返回语句,则在解析从fetchData返回的promise之前,测试将完成,然后((有机会执行回调。

您的测试应该是

it('should catch and re-throw error', () => {
return expect(foo()).rejects.toEqual(expect.anything());
});

正如u/Bergi在async/await中注意到的那样,它看起来可能更简洁:

it('should catch and re-throw error', async () => {
await expect(foo()).rejects.toEqual(expect.anything());
});

但如果我们错过了在expect之前添加await,我们将遇到与没有return的版本1完全相同的问题。所以要小心。

最新更新