[英]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.