【发布时间】:2019-07-23 18:22:19
【问题描述】:
我有一个“容器组件”,DashboardContainer,它连接到一个 redux 存储。
在 index.js 的上一层,store Provider 封装了一个 AppRouter 组件,如下所示:
<Provider store={store}>
<AppRouter />
</Provider>
AppRouter 设置如下:
const AppRouter = () => (
<Router history={history}>
<Switch>
<PublicRoute exact path={ROUTES.LANDING} component={SignUpPage} />
<PrivateRoute path={ROUTES.DASHBOARD} component={DashboardContainer} />
<Route component={NotFoundPage} />
</Switch>
</Router>
);
因此,简而言之,我尝试测试的方法位于 redux 和路由器包装器之下。
这是带有方法的组件,我正在尝试测试:
import React, { Component } from "react";
import { connect } from "react-redux";
import Dashboard from "./Dashboard";
import PropTypes from "prop-types";
import moment from "moment";
class DashboardContainer extends Component {
static propTypes = {
dashboardDate: PropTypes.string.isRequired,
exerciseLog: PropTypes.array.isRequired
};
componentDidMount() {
this.props.setDashboardDate(moment().format());
}
getExerciseCalsForDay = () => {
const { dashboardDate, exerciseLog } = this.props;
const totalCals = exerciseLog
.filter(entry => {
return moment(dashboardDate).isSame(entry.date, "day");
})
.map(entry => {
return entry.workouts
.map(item => item.nf_calories || 0)
.reduce((acc, curr) => acc + curr, 0);
});
return totalCals[0] || 0;
};
render() {
return (
<Dashboard
exerciseCalsToday={this.getExerciseCalsForDay()}
exerciseLog={this.props.exerciseLog}
/>
);
}
}
const mapStateToProps = state => ({
dashboardDate: state.dashboard.dashboardDate,
exerciseLog: state.exerciseLog
});
export default connect(mapStateToProps)(DashboardContainer);
一些注意事项:
- 我不想测试 React Router 或 Redux。
- 我没有在任何 HOC 中使用 {withRouter}。
- 我并不是要测试是否或如何调用该方法。
- 所有我想做的是看看方法是否返回正确的值,给定一个通过道具提供的数据集,这些道具是在测试中提供的。
- 我在这里和 Github repo 上阅读了几篇关于 Enzyme 的文章(例如 link),相信我需要使用dive()。
- DashboardContainer 实际上不渲染任何东西,除了 是孩子们。它对从接收到的数据执行计算 redux 存储,并将此处理后的数据传递给子级 用于在那里呈现的“展示性”组件。
- 在子组件中进行测试无济于事,因为它们正在接收 计算值作为道具,正确渲染。
这是我正在进行的测试:
import React from "react";
import { shallow } from "enzyme";
import DashboardContainer from "../../../components/Dashboard/DashboardContainer";
import data from "../../fixtures/ExerciseLogSeedData";
const props = {
dashboardDate: "2019-03-01T19:07:17+07:00",
foodLog: data
};
const wrapper = shallow(<DashboardContainer {...props} />);
const instance = wrapper.instance();
test("should correctly calculate exercise calories for the day", () => {
expect(instance.getExerciseCalsForDay()).toBe(1501);
});
本次测试的结果是:
TypeError: instance.getExerciseCalsForDay is not a function
如果我将实例的定义更改为:
const instance = wrapper.instance().dive();
我明白了:
TypeError: wrapper.instance(...).dive is not a function
如果我将实例更改为:
const instance = wrapper.dive().instance();
我明白了:
TypeError: ShallowWrapper::dive() can only be called on components
如果我尝试用这个来运行 except:
expect(instance.getExerciseCalsForDay).toBe(1501);
toBe() 接收“未定义”。
如果我尝试使用 mount 而不是 shallow ,所有的地狱都会失败,因为我还没有实现模拟存储等。
问题:没有将方法直接复制到测试中(并使其成为函数),如何正确定位这样的方法以便能够运行期望/toBe它?是潜水的地方吗?还是我错过了整个事情的一些基本方面?
【问题讨论】:
标签: reactjs redux react-router jestjs enzyme