You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

测试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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 13:45:31