React/ReduxToolkit testing failed with "TypeError: Cannot read property 'pending' of undefined" when using Async Thunks
React/ReduxToolkit testing failed with "TypeError: Cannot read property 'pending' of undefined" when using Async Thunks
编辑:问题已解决=> https://github.com/reduxjs/redux-toolkit/issues/1609
感谢@markerikson
我目前正在尝试将测试设置到我使用 React 和 ReduxToolkit 的项目中。对于异步操作,我使用来自 @reduxjs/toolkit
的 createAsyncThunk
。我将所有这些操作分离到单独的文件中,然后我将它们导入到包含“切片”的文件中,以便能够像这样将它们用于 extraReducers
:
import { myAsyncThunk } from './some-thunks.file.ts';
const mySlice = createSlice({
....blah blah,
extraReducers: {
[myAsyncThunk.pending.type]: state => {...},
[myAsyncThunk.rejected.type]: state => {...},
[myAsyncThunk.fulfilled.type]: state => {...},
}
})
使用该方法一切正常,没有任何问题,但我在尝试 运行 测试时遇到问题..
我遵循了 @reduxjs/toolkit
文档并围绕 @testing-library/react
的渲染方法做了一个包装器,如下所示:(*我还包括路由器提供程序)
import { Provider } from 'react-redux';
import { Router } from 'react-router-dom';
import { render as rtlRender } from '@testing-library/react';
import { configureStore } from '@reduxjs/toolkit';
import history from '../../history';
import { reducer } from '../store/index';
function render(ui, { preloadedState, store = configureStore({ reducer, preloadedState }), ...renderOptions } = {}) {
function Wrapper({ children }) {
return (
<Provider store={store}>
<Router history={history}>{children}</Router>
</Provider>
);
}
return rtlRender(ui, { wrapper: Wrapper, ...renderOptions });
}
export * from '@testing-library/react';
export { render };
然后我编写了 ULTRA 简单测试,例如:
import { render } from '../../my-custom-render.ts';
import SigninComponent from './signin.component';
describe('SigninComponent', () => {
const { baseElement } = render(<SigninComponent />);
it('should render', async () => {
expect(baseElement).toBeTruthy();
});
});
问题来了...我在尝试 运行 测试时遇到以下错误:
FAIL my-application ...path-to-component/signin/signin.component.spec.tsx
● Test suite failed to run
TypeError: Cannot read property 'pending' of undefined
86 | },
87 | extraReducers: {
> 88 | [getOrdersList.pending.type]: state => {
| ^
89 | state.isLoading = true;
90 | },
91 | [getOrdersList.rejected.type]: state => {
at Object.<anonymous> (src/app/store/features/orders/orders.slice.ts:88:18)
at Object.<anonymous> (src/app/store/features/actions.export.ts:3:1)
at Object.<anonymous> (src/app/store/features/orders/orders.async.ts:14:1)
at Object.<anonymous> (src/app/store/features/apiRoot/apiRoot.slice.ts:17:1)
at Object.<anonymous> (src/app/store/index.ts:3:1)
at Object.<anonymous> (src/app/utils/table.util.tsx:5:1)
at Object.<anonymous> (src/app/utils/_index.ts:3:1)
at Object.<anonymous> (src/app/routes/auth/signin/signin.component.spec.tsx:1:1)
at TestScheduler.scheduleTests (../../node_modules/@jest/core/build/TestScheduler.js:333:13)
at runJest (../../node_modules/@jest/core/build/runJest.js:387:19)
at _run10000 (../../node_modules/@jest/core/build/cli/index.js:408:7)
at Object.runCLI (../../node_modules/@jest/core/build/cli/index.js:261:3)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 8.615 s
Ran all test suites.
我发现,如果异步 thunk 不在单独的文件中,而是在与切片相同的文件中(*不只是在那里导入),则一切正常并且测试通过。 (*我的应用程序已经相当大,所以对我来说,将所有异步 thunk 移动到与切片相同的文件中不是一个选项)
另一个问题是“有问题的”异步 thunk 实际上并不是我要测试的组件的一部分。它来自完全不同的模块,但我认为那是因为我在包装渲染时将我的整个状态传递给提供者。
所以我希望我对我的问题的描述足够好以便理解,如果有人知道如何解决该问题,我将不胜感激!
提前致谢!
由于有人在 https://github.com/reduxjs/redux-toolkit/issues/1609 中提出并回答了这个问题,我将在此处粘贴答案以提高可见性:
这表明您遇到了循环导入问题,这导致导入的变量在运行时未定义。您必须弄清楚导入圈中涉及哪些文件,并重新安排代码以避免这种情况。 Webpack https://github.com/aackerman/circular-dependency-plugin can help identify which files are the issue here. See https://redux-toolkit.js.org/usage/usage-guide#exporting-and-using-slices 有关重新排列逻辑的一些建议。
附带说明一下,我们建议对 extraReducers
使用“构建器回调”语法,而不是“对象查找 table”形式:
https://redux-toolkit.js.org/api/createSlice#the-extrareducers-builder-callback-notation
编辑:问题已解决=> https://github.com/reduxjs/redux-toolkit/issues/1609 感谢@markerikson
我目前正在尝试将测试设置到我使用 React 和 ReduxToolkit 的项目中。对于异步操作,我使用来自 @reduxjs/toolkit
的 createAsyncThunk
。我将所有这些操作分离到单独的文件中,然后我将它们导入到包含“切片”的文件中,以便能够像这样将它们用于 extraReducers
:
import { myAsyncThunk } from './some-thunks.file.ts';
const mySlice = createSlice({
....blah blah,
extraReducers: {
[myAsyncThunk.pending.type]: state => {...},
[myAsyncThunk.rejected.type]: state => {...},
[myAsyncThunk.fulfilled.type]: state => {...},
}
})
使用该方法一切正常,没有任何问题,但我在尝试 运行 测试时遇到问题..
我遵循了 @reduxjs/toolkit
文档并围绕 @testing-library/react
的渲染方法做了一个包装器,如下所示:(*我还包括路由器提供程序)
import { Provider } from 'react-redux';
import { Router } from 'react-router-dom';
import { render as rtlRender } from '@testing-library/react';
import { configureStore } from '@reduxjs/toolkit';
import history from '../../history';
import { reducer } from '../store/index';
function render(ui, { preloadedState, store = configureStore({ reducer, preloadedState }), ...renderOptions } = {}) {
function Wrapper({ children }) {
return (
<Provider store={store}>
<Router history={history}>{children}</Router>
</Provider>
);
}
return rtlRender(ui, { wrapper: Wrapper, ...renderOptions });
}
export * from '@testing-library/react';
export { render };
然后我编写了 ULTRA 简单测试,例如:
import { render } from '../../my-custom-render.ts';
import SigninComponent from './signin.component';
describe('SigninComponent', () => {
const { baseElement } = render(<SigninComponent />);
it('should render', async () => {
expect(baseElement).toBeTruthy();
});
});
问题来了...我在尝试 运行 测试时遇到以下错误:
FAIL my-application ...path-to-component/signin/signin.component.spec.tsx
● Test suite failed to run
TypeError: Cannot read property 'pending' of undefined
86 | },
87 | extraReducers: {
> 88 | [getOrdersList.pending.type]: state => {
| ^
89 | state.isLoading = true;
90 | },
91 | [getOrdersList.rejected.type]: state => {
at Object.<anonymous> (src/app/store/features/orders/orders.slice.ts:88:18)
at Object.<anonymous> (src/app/store/features/actions.export.ts:3:1)
at Object.<anonymous> (src/app/store/features/orders/orders.async.ts:14:1)
at Object.<anonymous> (src/app/store/features/apiRoot/apiRoot.slice.ts:17:1)
at Object.<anonymous> (src/app/store/index.ts:3:1)
at Object.<anonymous> (src/app/utils/table.util.tsx:5:1)
at Object.<anonymous> (src/app/utils/_index.ts:3:1)
at Object.<anonymous> (src/app/routes/auth/signin/signin.component.spec.tsx:1:1)
at TestScheduler.scheduleTests (../../node_modules/@jest/core/build/TestScheduler.js:333:13)
at runJest (../../node_modules/@jest/core/build/runJest.js:387:19)
at _run10000 (../../node_modules/@jest/core/build/cli/index.js:408:7)
at Object.runCLI (../../node_modules/@jest/core/build/cli/index.js:261:3)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 8.615 s
Ran all test suites.
我发现,如果异步 thunk 不在单独的文件中,而是在与切片相同的文件中(*不只是在那里导入),则一切正常并且测试通过。 (*我的应用程序已经相当大,所以对我来说,将所有异步 thunk 移动到与切片相同的文件中不是一个选项) 另一个问题是“有问题的”异步 thunk 实际上并不是我要测试的组件的一部分。它来自完全不同的模块,但我认为那是因为我在包装渲染时将我的整个状态传递给提供者。
所以我希望我对我的问题的描述足够好以便理解,如果有人知道如何解决该问题,我将不胜感激!
提前致谢!
由于有人在 https://github.com/reduxjs/redux-toolkit/issues/1609 中提出并回答了这个问题,我将在此处粘贴答案以提高可见性:
这表明您遇到了循环导入问题,这导致导入的变量在运行时未定义。您必须弄清楚导入圈中涉及哪些文件,并重新安排代码以避免这种情况。 Webpack https://github.com/aackerman/circular-dependency-plugin can help identify which files are the issue here. See https://redux-toolkit.js.org/usage/usage-guide#exporting-and-using-slices 有关重新排列逻辑的一些建议。
附带说明一下,我们建议对 extraReducers
使用“构建器回调”语法,而不是“对象查找 table”形式:
https://redux-toolkit.js.org/api/createSlice#the-extrareducers-builder-callback-notation