[英]How to test that an error is re-thrown in a catch statement with Jest
我有一个返回 promise 的 function,但我想测试它是否定义了一个 catch,然后另外测试它是否重新抛出错误。
这是一个非常人为的例子,但它是展示问题的最清晰的方式。 在我的实际代码中,我正在调用模拟失败的 function(与此示例中的手动拒绝相比),并且我在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();
});
我可以成功检查日志记录 function 是否被调用,但无法弄清楚如何确保错误在之后重新抛出。
感谢@skyboyer和@Bergi让我以不同的方式思考这个问题,并让我接触到一些有趣的笑话
下面是显示日志记录 function 的更新代码,以及我确定的更新测试。
导致这种情况的问题是
logging
被调用抓住被拒绝的 promise 让我可以做到这两点。
我本来打算在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 之前完成,然后 then() 有机会执行回调。
你的测试应该是
it('should catch and re-throw error', () => {
return expect(foo()).rejects.toEqual(expect.anything());
});
正如你/Bergi 注意到的那样, async/await
看起来更简洁:
it('should catch and re-throw error', async () => {
await expect(foo()).rejects.toEqual(expect.anything());
});
但是如果我们错过了在expect
之前添加await
,我们将遇到与没有return
的版本 1 中完全相同的问题。 所以要小心。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.