无法使用redux-toolkit RTK-Query运行测试:TypeError:无法读取未定义的属性“injectEndpoints”

unhi4e5o  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(97)

尝试运行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 }) };
}


设置测试:

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';
            })
....

svujldwt

svujldwt1#

我不能确定,我不再访问这个项目,但据我所知,问题是由调用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: () => ({}),
});

字符串

相关问题