迁移至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
相关产品推荐
相关产品推荐

