Jest中Axios Spy调用次数不符合预期问题排查
问题:Jest测试中Axios Spy未捕获到两次请求调用
我正在测试一个用于检查应用更新的React Context,其中包含checkForUpdate函数,代码如下:
async function checkForUpdate() { if (isPlatform('capacitor')) { const maintanenceURL = 'https://example.com/maintenance.json'; const updateURL = 'https://example.com/update.json'; try { const maintanenceFetch: AxiosResponse<MaintanenceDataInterface> = await axios.get(maintanenceURL); console.log('maintain', maintanenceFetch); if (maintanenceFetch.data.enabled) { setUpdateMessage(maintanenceFetch.data.msg); return; } const updateFetch: AxiosResponse<UpdateDataInterface> = await axios.get( updateURL ); console.log('updateFetch', updateFetch); if (updateFetch.data.enabled) { const capApp = await App.getInfo(); const capAppVersion = capApp.version; console.log('Thi is a thinkg', capAppVersion); if (isPlatform('android')) { console.log('hi'); const { currentAndroid, majorMsg, minorMsg } = updateFetch.data; const idealVersionArr = currentAndroid.split('.'); const actualVersionArr = capAppVersion.split('.'); if (idealVersionArr[0] !== actualVersionArr[0]) { setUpdateMessage(majorMsg); setUpdateAvailable(true); return; } if (idealVersionArr[1] !== actualVersionArr[1]) { setUpdateMessage(minorMsg); setUpdateAvailable(true); return; } } else { const { currentIos, majorMsg, minorMsg } = updateFetch.data; const idealVersionArr = currentIos.split('.'); const actualVersionArr = capAppVersion.split('.'); if (idealVersionArr[0] !== actualVersionArr[0]) { setUpdateMessage(majorMsg); setUpdateAvailable(true); return; } if (idealVersionArr[1] !== actualVersionArr[1]) { setUpdateMessage(minorMsg); setUpdateAvailable(true); return; } } } } catch (err) { console.log('Error in checkForUpdate', err); } } }
控制台显示两次axios.get请求均已执行,但我编写的Jest测试用例中,axiosSpy仅记录到1次调用,与预期的2次不符,无法定位问题。测试代码如下:
it.only('should render the update page if the fetch call to update bucket is enabled and returns a different major version', async () => { const isPlatformSpy = jest.spyOn(ionicReact, 'isPlatform'); isPlatformSpy.mockReturnValueOnce(true).mockReturnValueOnce(true); const appSpy = jest.spyOn(App, 'getInfo'); appSpy.mockResolvedValueOnce({ version: '0.8.0', name: 'test', build: '123', id: 'r132-132', }); const axiosSpy = jest.spyOn(axios, 'get'); axiosSpy .mockResolvedValueOnce({ data: { enabled: false, msg: { title: 'App maintenance', msg: 'We are currently solving an issue where users cannot open the app. This should be solved by end of day 12/31/2022! Thank you for your patience 😁', btn: 'Ok', type: 'maintenance', }, }, }) .mockResolvedValueOnce({ data: { current: '1.0.0', currentAndroid: '1.0.0', currentIos: '2.0.0', enabled: true, majorMsg: { title: 'Important App update', msg: 'Please update your app to the latest version to continue using it. If you are on iPhone, go to the app store and search MO Gas Tax Back to update your app. The button below does not work but will in the current update!', btn: 'Download', type: 'major', }, minorMsg: { title: 'App update available', msg: "There's a new version available, would you like to get it now?", btn: 'Download', type: 'minor', }, }, }); customRender(<UpdateChild />); expect(axiosSpy).toHaveBeenCalledTimes(2); });
解决思路
等待异步操作完成:
checkForUpdate是异步函数,测试中渲染组件后,需要等待异步流程执行完毕再做断言。用waitFor包裹断言:await waitFor(() => { expect(axiosSpy).toHaveBeenCalledTimes(2); });或者如果能直接从Context中调用
checkForUpdate,可以直接等待该函数执行:await checkForUpdate(); expect(axiosSpy).toHaveBeenCalledTimes(2);修正
isPlatform的mock:函数中第二次调用isPlatform('android'),测试里只mock了两次返回true,后续调用会返回原始值。改为永久mock确保平台判断一致:isPlatformSpy.mockReturnValue(true);确认Axios实例绑定正确:如果项目中存在多个Axios实例,Spy可能未绑定到实际使用的实例上。直接mock整个Axios模块:
jest.mock('axios'); const mockedAxios = axios as jest.Mocked<typeof axios>; mockedAxios.get.mockResolvedValueOnce(/* 维护接口数据 */).mockResolvedValueOnce(/* 更新接口数据 */);
内容的提问来源于stack exchange,提问作者klaurtar1
相关产品推荐
相关产品推荐

