尝试测试使用 redux 的组件时,无法读取 属性 of undefined 错误
Error cannot read property of undefined when trying to test a component that uses redux
我有一个基于 class 的仪表板组件
class Dashboard extends Component {
...
render() {
return sth
}
}
const mapStateToProps = state => ({
userId: state.mainState.userId,
theme: state.mainState.theme,
companyUsers: state.mainState.companyUsers,
activities: state.mainState.activities,
activityTypes: state.mainState.activityTypes,
projects: state.mainState.projects
});
const mapDispatchToProps = {
setMainValue: actions.setMainValue
};
export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(Dashboard));
现在我正在尝试使用 jest 和 react-testing-library 开始测试组件。
我创建了一个类似于 article 的 renderWithProvider 函数,并尝试使用自定义渲染函数进行测试。唯一的区别是,在官方 redux 网站中,它 returns mapStateToProps 上的整个状态,因为它很短,而我只返回特定变量。
function renderWithProvider(ui, { initialState, ...renderOptions } = {}) {
const store = createStore(rootReducer, initialState, applyMiddleware(thunk));
function Wrapper({ children }) {
return <Provider store={store}>{children}</Provider>;
}
Wrapper.propTypes = {
children: PropTypes.node.isRequired
};
return rtlRender(ui, { wrapper: Wrapper, ...renderOptions });
}
// re-export everything
export * from '@testing-library/react';
// override render method
export { renderWithProvider };
当我渲染组件和 运行 测试时
import Dashboard from '.';
import { renderWithProvider } from '../testUtils/renderWithProvider'
test('should ', () => {
renderWithProvider(<Dashboard />, {
initialState: {
userId: 106,
theme: 'light',
companyUsers: [],
activities: [],
activityTypes: [],
projects: []
}
});
});
我得到:
TypeError: Cannot read property 'userId' of undefined
334 |
335 | const mapStateToProps = state => ({
336 | userId: state.mainState.userId,
欢迎提出任何建议
编辑:我也试过以下方法:
test('should ', () => {
renderWithProvider(<Dashboard />, {
initialState: {
mainState: {
userId: 106,
theme: 'light',
companyUsers: [],
activities: [],
activityTypes: [],
projects: []
}
}
});
});
但不断出现同样的错误
根据 mapStateToProps 中的预期结构,您的 initialValue 是错误的。您传递的这些属性需要是 mainState 属性 的子属性,而不是根状态的顶级属性。
经过大量挖掘,我发现问题最终与 history
库的使用和项目商店中 rootReducer(history)
的使用有关。
const store = createStore(
rootReducer(history),
composeEnhancers(applyMiddleware(routerMiddleware(history), thunk))
);
一旦我将 rootReducer
作为函数和 history 作为参数传递给 rootReducer,类似于在 renderWithProvider
中存储初始化 store.getState()
不再是 undedined
,因此 mainState 也及其值:
import { createBrowserHistory } from 'history';
const history = createBrowserHistory();
function renderWithProvider(ui, { initialState, ...renderOptions } = {}) {
const store = createStore(rootReducer(history), initialState,
applyMiddleware(thunk));
...
}
我有一个基于 class 的仪表板组件
class Dashboard extends Component {
...
render() {
return sth
}
}
const mapStateToProps = state => ({
userId: state.mainState.userId,
theme: state.mainState.theme,
companyUsers: state.mainState.companyUsers,
activities: state.mainState.activities,
activityTypes: state.mainState.activityTypes,
projects: state.mainState.projects
});
const mapDispatchToProps = {
setMainValue: actions.setMainValue
};
export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(Dashboard));
现在我正在尝试使用 jest 和 react-testing-library 开始测试组件。 我创建了一个类似于 article 的 renderWithProvider 函数,并尝试使用自定义渲染函数进行测试。唯一的区别是,在官方 redux 网站中,它 returns mapStateToProps 上的整个状态,因为它很短,而我只返回特定变量。
function renderWithProvider(ui, { initialState, ...renderOptions } = {}) {
const store = createStore(rootReducer, initialState, applyMiddleware(thunk));
function Wrapper({ children }) {
return <Provider store={store}>{children}</Provider>;
}
Wrapper.propTypes = {
children: PropTypes.node.isRequired
};
return rtlRender(ui, { wrapper: Wrapper, ...renderOptions });
}
// re-export everything
export * from '@testing-library/react';
// override render method
export { renderWithProvider };
当我渲染组件和 运行 测试时
import Dashboard from '.';
import { renderWithProvider } from '../testUtils/renderWithProvider'
test('should ', () => {
renderWithProvider(<Dashboard />, {
initialState: {
userId: 106,
theme: 'light',
companyUsers: [],
activities: [],
activityTypes: [],
projects: []
}
});
});
我得到:
TypeError: Cannot read property 'userId' of undefined
334 | 335 | const mapStateToProps = state => ({ 336 | userId: state.mainState.userId,
欢迎提出任何建议
编辑:我也试过以下方法:
test('should ', () => {
renderWithProvider(<Dashboard />, {
initialState: {
mainState: {
userId: 106,
theme: 'light',
companyUsers: [],
activities: [],
activityTypes: [],
projects: []
}
}
});
});
但不断出现同样的错误
根据 mapStateToProps 中的预期结构,您的 initialValue 是错误的。您传递的这些属性需要是 mainState 属性 的子属性,而不是根状态的顶级属性。
经过大量挖掘,我发现问题最终与 history
库的使用和项目商店中 rootReducer(history)
的使用有关。
const store = createStore(
rootReducer(history),
composeEnhancers(applyMiddleware(routerMiddleware(history), thunk))
);
一旦我将 rootReducer
作为函数和 history 作为参数传递给 rootReducer,类似于在 renderWithProvider
中存储初始化 store.getState()
不再是 undedined
,因此 mainState 也及其值:
import { createBrowserHistory } from 'history';
const history = createBrowserHistory();
function renderWithProvider(ui, { initialState, ...renderOptions } = {}) {
const store = createStore(rootReducer(history), initialState,
applyMiddleware(thunk));
...
}