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

迁移至Vite+Vitest后RTK Query injectEndpoints报错求助

问题:RTK Query使用injectEndpoints后测试报错"Cannot read properties of undefined (reading 'injectEndpoints')"

将项目从Create React App(CRA)迁移到Vite,同时将测试框架切换为Vitest,保留React Testing Library进行测试。迁移完成后,为提升可读性和可维护性,将原本集中在单个文件的RTK Query端点拆分,使用injectEndpoints扩展端点,这一修改导致测试失败,报错信息为:

Cannot read properties of undefined (reading 'injectEndpoints')

测试中使用Mock Service Worker(MSW)模拟接口请求,迁移和端点重构前一切正常。以下是相关配置和代码片段:

测试代码

describe('Wall of experts', () => {
const user = {
    "givenName": "XXXX",
    "familyName": "XXXXX",
    "name": "XXXXX",
    "departmentnumber": "XXX",
    "email": "XXXXXXXXXXXX",
    "sub": "XXXXX",
    "authorities": ["XXXX", 'XX']
}

beforeAll(() => {
    initI18nMock({})
    add18nResourcesMock({
        "maintenance": {
            "infoTexts": {
                "user-email-address": "User email",
            }
        },
        "expertWall": {
            "infoTexts": {
                "success-update-message": "User has been successful updated",
                "success-remove-message": "User has been successful deleted",
                "success-add-message": "User has been successful added"
            }
        }
    })

    server.listen()
    store.dispatch(setLoggedUser(user))
})

afterEach(() => {
    // Cleanup
    add18nResourcesMock({})
    server.resetHandlers()
})

afterAll(() => {
    server.close()
})

it('should display wall of experts', async () => {
    customRender(<><AppSnackbar/><ExpertWall/></>)

    await screen.findAllByTestId('user')

    const displayedUsers = screen.queryAllByTestId('user')

    // Check rendered users amount against mocked data.
    expect(displayedUsers).toHaveLength(mockWallOfExperts.length)

})

Test Utils配置(适配Vite的React Testing Library配置)

afterEach(() => {
    cleanup()
})

const AllTheProviders = ({ children }: {children: React.ReactElement}) => {
    return (
        <BrowserRouter basename={'/'}>
            <Provider store={store}>{children}</Provider>
        </BrowserRouter>
    );
};

function customRender(ui: React.ReactElement, options= {})  {
    return render(ui, { wrapper: AllTheProviders, ...options });
}

export * from '@testing-library/react'
export { default as userEvent } from '@testing-library/user-event'
// override render export
export { customRender as render }

Redux Store配置

const store = configureStore({
    reducer: {
        [datenlandkarteApi.reducerPath]: datenlandkarteApi.reducer,
        [cloudBMWApi.reducerPath]: cloudBMWApi.reducer,
        datenTicket: datenTicketReducer,
        dataRequestWizard: dataRequestWizardReducer,
        main: mainReducer,
    },
    middleware: (getDefaultMiddleware) =>
        getDefaultMiddleware().concat(datenlandkarteApi.middleware, cloudBMWApi.middleware),
});
export type RootState = ReturnType<typeof store.getState>;

export type AppDispatch = typeof store.dispatch;

export default store;

主API文件(部分代码)

export const apiName = createApi({
    reducerPath: 'apiName ',
    baseQuery: fetchBaseQuery({
        mode: 'cors',
        baseUrl: `${baseUrl}/api/`,
        prepareHeaders: (headers) => {
            const token = getAccessToken();
            if (token) {
                headers.set('Authorization', `Bearer ${token}`);
                // headers.set('Accept', `application/json`);
            }
            return headers;
        },
    }),
    tagTypes: rtkTagTypesValues,
    endpoints: (build) => ({
        // GETTERS i.e. RTK query
        getPerson: build.query<api.PersonDTO, string>({
            query: (email) => ({
                url: `person/getByEmail/${email}`,
                responseHandler: mapToJson,
            }),
        }),

注入端点的代码

const useCasePurposeApi = datenlandkarteApi.injectEndpoints({
    endpoints: (build) => ({
        getUseCasePurposes: build.query<UseCasePurposesShortDto, GetUseCasePurposesRequestDto>({
            query: ({ useCaseRef, pageNumber = 0, pageSize = 5 }) => {
                return {
                    url: `sec/use-case-purposes/${useCaseRef}/short?pageNumber=${pageNumber}&pageSize=${pageSize}`,
                };
            },
            providesTags: (result) => {
                if (result) {
                    return [RtkTagTypes.ALL_PRIVACY_PURPOSE];
                }
                return [];
            },
        }),

已查阅Vite、Vitest及RTK Query关于injectEndpoints的文档和示例,但仍无法定位问题原因,希望得到解决该问题、让测试在新配置下通过的建议。

补充想法

问题可能与RTK Query相关,或许需要以某种方式mock injectEndpoints,但不确定具体操作方法。若有类似问题的解决经验或在该配置下mock RTK Query的经验,欢迎提供建议。


内容的提问来源于stack exchange,提问作者Mati

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 07:48:12