我有一个fetcher
函数,它最终只是从 API 中获取东西。在 Jest 中,我想以多种方式测试此功能。为了模拟我使用的 API 响应jest-fetch-mock
。
如果服务器响应错误,以下代码段测试函数是否引发错误。这个很好用!
// works fine!
import fetchMock from 'jest-fetch-mock';
...
it('throw an error if http status is not 2xx', async () => {
(fetch as typeof fetchMock).mockResponseOnce(JSON.stringify({body: "ok"}), { status: 400 });
await expect(fetcher(url)).rejects.toThrowError()
});
第二个测试应该测试函数是否抛出错误,如果服务器太慢。这个不行。因为我不知道如何等待该fetcher
函数并jest.runAllTimers()
并行运行。如果我不等待fetcher
它返回一个承诺的功能。如果我不这样做runAllTimers
,开玩笑的测试将在它抛出之前超时。
// does NOT work!
import fetchMock from 'jest-fetch-mock';
...
it('throw an error if request timed out', async () => {
jest.useFakeTimers();
(fetch as typeof fetchMock).mockResponseOnce(() =>
// simulate 10 second response time
new Promise(resolve => setTimeout(() => resolve({ body: 'ok' }), 10000))
)
jest.runAllTimers();
await expect(fetcher(url)).rejects.toThrowError()
});
关于如何等待异步函数的任何想法应该抛出但也将所有计时器运行为零?
仅供参考,这里是 fetcher 的基本代码:
export default async function fetcher<JSON = any>(
input: RequestInfo,
init?: RequestInit,
): Promise<JSON> {
try {
const timeout = 5000;
const res = await new Promise<Response>(async (resolve, reject) => {
const requestTimeoutObserver = setTimeout(() => {
reject('request timeout');
}, timeout);
const response = await fetch(input, init);
clearTimeout(requestTimeoutObserver);
resolve(response);
})
if (!res || !res.ok) {
throw new Error("a new error");
}
return res.json();
} catch (error: any) {
// report error
throw error;
}
}