如何用Jest为React Native中.catch()内的Error函数编写测试用例
测试React Native中handleRefresh的catch分支及状态更新
要测试handleRefresh的.catch()分支,核心是mock第三方库的refresh函数让它返回rejected状态的Promise,然后验证onError被触发,同时检查两个状态更新函数是否传入了预期值。以下是具体实现方案:
步骤1:Mock第三方库的refresh函数
假设refresh是从某个第三方模块(比如'network-utils')导入的,在测试文件顶部用Jest mock整个模块,强制让refresh返回被拒绝的Promise:
import { refresh } from 'network-utils'; // Mock第三方模块,让refresh返回失败的Promise jest.mock('network-utils', () => ({ refresh: jest.fn().mockRejectedValue(new Error('Mock refresh failure')), }));
步骤2:编写测试用例(分两种场景)
场景A:组件内的函数测试
如果代码属于某个React Native组件,结合@testing-library/react-native编写测试:
import { render, screen, fireEvent } from '@testing-library/react-native'; import WifiComponent from './WifiComponent'; import { refresh } from 'network-utils'; import { NetworkStatus } from './WifiComponent'; import React from 'react'; describe('WifiComponent - handleRefresh error scenario', () => { beforeEach(() => { // 重置mock状态,避免用例间污染 jest.clearAllMocks(); }); it('triggers onError and updates states when refresh fails', async () => { // 模拟useState的setter,用于直接验证调用参数 const mockSetWifiStatus = jest.fn(); const mockSetWifiDetails = jest.fn(); jest.spyOn(React, 'useState') .mockImplementationOnce(() => [NetworkStatus.CONNECTED, mockSetWifiStatus]) .mockImplementationOnce(() => [{ ssid: 'Test' }, mockSetWifiDetails]); // 渲染组件并触发刷新 render(<WifiComponent />); fireEvent.press(screen.getByText('Refresh Wifi')); // 等待异步Promise处理完成 await new Promise(resolve => setImmediate(resolve)); // 验证refresh函数被调用 expect(refresh).toHaveBeenCalledTimes(1); // 验证状态更新函数传入了正确参数 expect(mockSetWifiStatus).toHaveBeenCalledWith(NetworkStatus.NOT_CONNECTED); expect(mockSetWifiDetails).toHaveBeenCalledWith(null); }); });
场景B:自定义Hook内的函数测试
如果代码属于自定义Hook,用@testing-library/react-hooks的renderHook测试:
import { renderHook, act } from '@testing-library/react-hooks'; import { useWifiRefresh } from './useWifiRefresh'; import { refresh } from 'network-utils'; import { NetworkStatus } from './useWifiRefresh'; describe('useWifiRefresh - handleRefresh error scenario', () => { beforeEach(() => { jest.clearAllMocks(); }); it('updates states to NOT_CONNECTED and null when refresh fails', async () => { // 渲染自定义Hook const { result } = renderHook(() => useWifiRefresh()); // 触发刷新操作 await act(async () => { result.current.handleRefresh(); }); // 验证refresh被调用 expect(refresh).toHaveBeenCalled(); // 验证最终状态值 expect(result.current.wifiStatus).toBe(NetworkStatus.NOT_CONNECTED); expect(result.current.wifiDetails).toBeNull(); }); });
关键注意事项
- 异步等待:
handleRefresh是异步操作,必须用await或setImmediate等待Promise处理完毕,否则断言会提前执行导致失败。 - Mock隔离:每个测试用例前重置mock状态,避免不同用例的mock结果互相干扰。
- 状态验证方式:可以选择直接验证setter的调用参数,也可以通过组件渲染的UI元素间接验证状态(比如检查是否显示"未连接"文本),根据测试需求选择即可。
内容的提问来源于stack exchange,提问作者Manya Sharma
相关产品推荐
相关产品推荐

