测试Redux Toolkit Query返回空集合,疑为Provider问题
问题:RTK Query组件测试时data返回undefined
我有如下代码文件:
1. features/postsSlice.js
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; export const postsSlice = createApi({ // Reducer Path 是Redux调试面板中显示的名称 reducerPath: "postsSlice", baseQuery: fetchBaseQuery({ baseUrl: process.env.REACT_APP_BACKEND_URL, }), // 通过tag type可以失效缓存 tagTypes: ['posts'], endpoints: (builder) => ({ getPosts: builder.query({ query: () => "/posts" }) }) }); export const { useGetPostsQuery } = postsSlice;
2. 组件GenericList.js
import React from "react" import { useGetPostsQuery } from "../features/postsSlice" export const GenericList = () => { const { data: posts, } = useGetPostsQuery(); console.log(posts) if (posts && posts.length > 0) { return ( posts.map(post => { return <p key={post.id}>{post.body}</p> }) ) } return <p>No data to shown</p> }
3. store/index.js
import { configureStore } from "@reduxjs/toolkit"; import { setupListeners } from "@reduxjs/toolkit/dist/query"; import { postsSlice } from "../features/postsSlice"; export const store = configureStore({ reducer: { [postsSlice.reducerPath]: postsSlice.reducer }, middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(postsSlice.middleware), }) setupListeners(store.dispatch);
项目运行正常,但用Jest和msw测试时,控制台console.log(posts)输出undefined:
PASS src/__tests__/components/GenericList.test.js ● Console console.log undefined at GenericList (src/components/GenericList.js:10:13) console.log undefined at GenericList (src/components/GenericList.js:10:13) PASS src/__tests__/App.test.js ● Console console.log undefined at GenericList (src/components/GenericList.js:10:13) console.log undefined at GenericList (src/components/GenericList.js:10:13)
编辑1:我完全移除了msw的mock,让测试调用真实API,结果还是输出undefined,因此怀疑是<Provider>的实现有问题。
解决方案
1. 确认测试中正确包裹Redux Provider
RTK Query的hooks依赖Redux store,测试组件时必须用<Provider>包裹组件并传入store,否则hooks无法获取到数据。
示例测试代码:
import { render } from '@testing-library/react'; import { Provider } from 'react-redux'; import { store } from '../../store'; import { GenericList } from '../GenericList'; test('渲染列表数据', async () => { render( <Provider store={store}> <GenericList /> </Provider> ); // 后续断言逻辑 });
2. 处理RTK Query的异步状态
useGetPostsQuery是异步请求,组件初始渲染时data就是undefined,测试时需要等待请求完成,不能同步断言数据。
修改测试代码,使用waitFor等待数据加载:
import { render, screen, waitFor } from '@testing-library/react'; import { Provider } from 'react-redux'; import { store } from '../../store'; import { GenericList } from '../GenericList'; test('数据加载完成后渲染列表', async () => { render( <Provider store={store}> <GenericList /> </Provider> ); // 等待数据加载完成,断言内容出现 await waitFor(() => { expect(screen.getByText(/示例帖子内容/i)).toBeInTheDocument(); }); });
3. 检查测试环境的环境变量
测试环境中process.env.REACT_APP_BACKEND_URL可能未配置,导致请求地址错误无法获取数据。可以在测试文件顶部手动设置:
process.env.REACT_APP_BACKEND_URL = 'https://jsonplaceholder.typicode.com';
4. 确保测试用store配置正确
如果使用独立的测试store,要确保正确集成RTK Query的reducer和middleware:
// 测试专用store import { configureStore } from '@reduxjs/toolkit'; import { postsSlice } from '../../features/postsSlice'; export const testStore = configureStore({ reducer: { [postsSlice.reducerPath]: postsSlice.reducer, }, middleware: (getDefault) => getDefault().concat(postsSlice.middleware), });
内容的提问来源于stack exchange,提问作者sineverba
相关产品推荐
相关产品推荐

