求Expo React Native项目中含RTK Query Hooks组件的测试步骤
在Expo React Native中测试RTK Query Hooks组件的可行方案
因为MSW不支持React Native环境,直接使用会触发不兼容错误,这里提供两种实用的测试方案,覆盖不同测试场景:
方案一:直接Mock RTK Query生成的Hooks
这种方法无需配置Redux Store,专注测试组件的UI逻辑,适合快速验证不同状态下的组件表现。
步骤:
- 在测试文件中mock目标Hook,保留原API切片的其他导出(避免影响其他逻辑)
- 为不同测试用例设置Hook的返回值(加载中、成功、错误三种核心状态)
- 渲染组件并断言UI表现
示例代码:
import { render, screen } from '@testing-library/react-native'; import MyComponent from '../MyComponent'; import { useGetDataQuery } from '../apiSlice'; // Mock RTK Query的Hook,保留原模块的其他内容 jest.mock('../apiSlice', () => ({ ...jest.requireActual('../apiSlice'), useGetDataQuery: jest.fn(), })); describe('MyComponent', () => { // 测试加载状态 it('显示加载提示', () => { (useGetDataQuery as jest.Mock).mockReturnValue({ data: undefined, error: undefined, isLoading: true, }); render(<MyComponent />); expect(screen.getByText('加载中...')).toBeTruthy(); }); // 测试数据成功返回的场景 it('渲染获取到的数据', () => { const mockData = { id: 1, name: '测试内容' }; (useGetDataQuery as jest.Mock).mockReturnValue({ data: mockData, error: undefined, isLoading: false, }); render(<MyComponent />); expect(screen.getByText(mockData.name)).toBeTruthy(); }); // 测试错误状态 it('显示错误提示', () => { (useGetDataQuery as jest.Mock).mockReturnValue({ data: undefined, error: { status: 500, data: '服务器异常' }, isLoading: false, isError: true, }); render(<MyComponent />); expect(screen.getByText('加载失败:服务器异常')).toBeTruthy(); }); });
方案二:配置Mock Redux Store测试完整数据流
这种方法更贴近真实运行环境,可以验证RTK Query的请求触发、状态流转逻辑,适合需要测试组件与Redux交互的场景。
步骤:
- 创建测试专用的Redux Store,包含RTK Query的Reducer和Middleware
- 通过Store的dispatch方法mock目标Endpoint的响应结果
- 用Provider包裹组件后渲染,断言异步状态下的UI变化
示例代码:
import { render, screen, waitFor } from '@testing-library/react-native'; import { Provider } from 'react-redux'; import { configureStore } from '@reduxjs/toolkit'; import { apiSlice } from '../apiSlice'; import MyComponent from '../MyComponent'; describe('MyComponent', () => { let testStore; // 每个测试用例前初始化Store beforeEach(() => { testStore = configureStore({ reducer: { [apiSlice.reducerPath]: apiSlice.reducer, }, middleware: getDefaultMiddleware => getDefaultMiddleware().concat(apiSlice.middleware), }); }); // 测试成功获取数据的完整流程 it('加载完成后渲染数据', async () => { // Mock Endpoint的成功响应 testStore.dispatch(apiSlice.endpoints.getData.initiate(null, { forceRefetch: true, })).unwrap.mockResolvedValue({ id: 1, name: '测试内容' }); render( <Provider store={testStore}> <MyComponent /> </Provider> ); // 先断言加载状态 expect(screen.getByText('加载中...')).toBeTruthy(); // 等待异步数据返回后断言内容 await waitFor(() => { expect(screen.getByText('测试内容')).toBeTruthy(); }); }); // 测试错误处理流程 it('请求失败时显示错误信息', async () => { // Mock Endpoint的失败响应 testStore.dispatch(apiSlice.endpoints.getData.initiate(null, { forceRefetch: true, })).unwrap.mockRejectedValue({ status: 500, data: '服务器异常' }); render( <Provider store={testStore}> <MyComponent /> </Provider> ); await waitFor(() => { expect(screen.getByText('加载失败:服务器异常')).toBeTruthy(); }); }); });
注意事项
- 如果使用Expo的测试环境,确保已配置
jest-expo作为测试预设(在jest.config.js中设置preset: 'jest-expo') - 若组件中有触发请求的交互(比如按钮点击),可以用
fireEvent模拟操作,再断言状态变化 - 方案一适合单元测试,方案二适合集成测试,可根据需求选择
内容的提问来源于stack exchange,提问作者renuka devi
相关产品推荐
相关产品推荐

