无法使用 redux-toolkit RTK-Query 运行测试:TypeError:无法读取未定义的属性“injectEndpoints”
2022-10-17
1347
尝试使用 redux-toolkit rtk 查询运行第一个测试并收到 api 未定义的错误。我做错了什么?
● Test suite failed to run
TypeError: Cannot read property 'injectEndpoints' of undefined
33 | };
34 |
> 35 | export const authApi = api.injectEndpoints({
| ^
36 | endpoints: (build) => ({
37 | login: build.mutation<ILoginResponse, ILoginData>({
38 | query: ({ username, password, captchaToken }) => {
at Object.<anonymous> (src/api/auth.ts:35:28)
at Object.<anonymous> (src/features/auth/authSlice.ts:2:1)
at Object.<anonymous> (src/api/index.ts:10:1)
at Object.<anonymous> (src/mocks/handler.ts:3:1)
at Object.<anonymous> (src/mocks/server.ts:3:1)
at Object.<anonymous> (src/setupTests.ts:6:1)
at TestScheduler.scheduleTests (node_modules/@jest/core/build/TestScheduler.js:333:13)
at runJest (node_modules/@jest/core/build/runJest.js:404:19)
at _run10000 (node_modules/@jest/core/build/cli/index.js:320:7)
at runCLI (node_modules/@jest/core/build/cli/index.js:173:3)
这是我的测试:
it('should reset roleType on role change', () => {
renderWithProviders(
<Form
initialValues={{
role: 6,
roleType: 7,
companyId: 2,
}}
mutators={formMutators}
onSubmit={jest.fn()}
>
{({ form }) => (
<>
<RoleFields setValue={form.mutators.setValue} />
</>
)}
</Form>
);
});
这里什么都没有,只是尝试渲染而不出现错误。
这是 renderWithProviders 函数:
interface ExtendedRenderOptions extends Omit<RenderOptions, 'queries'> {
preloadedState?: PreloadedState<RootState>;
store?: AppStore;
}
export function renderWithProviders(
ui: React.ReactElement,
{
preloadedState = {},
// Automatically create a store instance if no store was passed in
store = setupStore(preloadedState),
...renderOptions
}: ExtendedRenderOptions = {}
) {
function Wrapper({ children }: PropsWithChildren<Record<string, unknown>>): JSX.Element {
return <Provider store={store}>{children}</Provider>;
}
// Return an object with the store and all of RTL's query functions
return { store, ...render(ui, { wrapper: Wrapper, ...renderOptions }) };
}
setupTests:
import '@testing-library/jest-dom/extend-expect';
import { server } from './mocks/server';
import { api } from './api';
import { setupStore } from './app/store';
const store = setupStore();
// Establish API mocking before all tests.
beforeAll(() => {
server.listen();
});
// Reset any request handlers that we may add during the tests,
// so they don't affect other tests.
afterEach(() => {
server.resetHandlers();
// This is the solution to clear RTK Query cache after each test
store.dispatch(api.util.resetApiState());
});
// Clean up after the tests are finished.
afterAll(() => server.close());
商店设置:
import { configureStore, ThunkAction, Action, combineReducers } from '@reduxjs/toolkit';
import type { PreloadedState } from '@reduxjs/toolkit';
import { api } from '../api';
import { authSlice } from '../features/auth/authSlice';
// Create the root reducer separately so we can extract the RootState type
const rootReducer = combineReducers({
[api.reducerPath]: api.reducer,
[authSlice.name]: authSlice.reducer,
});
export const setupStore = (preloadedState?: PreloadedState<RootState>) => {
return configureStore({
reducer: rootReducer,
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(api.middleware),
preloadedState,
});
};
请帮忙这里出了什么问题,不知道....
UPD: 看起来问题出在这里:
import { logout } from '../features/auth/authSlice';
....
const baseQueryWithAuthCheck: BaseQueryFn<
string | FetchArgs,
unknown,
FetchBaseQueryError
> = async (args, api, extraOptions) => {
const result = await baseQuery(args, api, extraOptions);
if (result.error && result.error.status === 401) {
api.dispatch(logout());
}
return result;
};
export const api = createApi({
reducerPath: 'api',
baseQuery: baseQueryWithAuthCheck,
tagTypes: ALL_TAGS_TYPES,
endpoints: () => ({}),
});
我正在从 authSlice 执行导入注销操作,并且 authSlice 从 api 导入以构建 extraReducers 的匹配器
import { authApi } from '../../api/auth';
....
export const authSlice = createSlice({
name: 'auth',
initialState,
reducers: {
logout: (state) => {
state.token = null;
authStorage.clear();
},
},
extraReducers: (builder) => {
builder
.addMatcher(authApi.endpoints.login.matchPending, (state) => {
state.loading = 'pending';
})
....
1个回答
我不能确定,我不再有权访问该项目,但据我记得,问题是由在 baseQuery 函数上调用 api 引起的,不知道为什么,但如果我删除这个调用,一切都正常
const baseQueryWithAuthCheck: BaseQueryFn<
string | FetchArgs,
unknown,
FetchBaseQueryError
> = async (args, api, extraOptions) => {
const result = await baseQuery(args, api, extraOptions);
if (result.error && result.error.status === 401) {
// the issue was caused because of this call
api.dispatch(logout());
}
return result;
};
export const api = createApi({
reducerPath: 'api',
baseQuery: baseQueryWithAuthCheck,
tagTypes: ALL_TAGS_TYPES,
endpoints: () => ({}),
});
Karine Hiulumian
2023-07-14