У меня есть «контейнерный компонент», DashboardContainer, который подключен к хранилищу с избыточностью.
На один уровень выше в index.js, поставщик магазина переносит компонент 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>
);
Итак, вкратце, метод, который я пытаюсь протестировать, расположен в оболочках редукса и маршрутизатора.
Вот компонент с методом, который я пытаюсь проверить:
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);
Несколько замечаний:
- IЯ не пытаюсь протестировать React Router или Redux.
- Я не использую {withRouter} в каких-либо HOC.
- Я не пытаюсь проверить, был ли вызван или вызван метод.
- Все Я пытаюсь выяснить, возвращает ли метод правильное значение, учитывая набор данных через реквизиты, которые предоставляются внутри теста.
- Я прочитал несколько постов здесь и в репозитории Github для Enzyme (например, link ) и считаю, что мне нужно использовать dive ().
- DashboardContainer на самом деле ничего не отображает, кромеэто дети.Он выполняет расчеты для данных, полученных из хранилища избыточных данных, и передает эти обработанные данные дочерним «презентационным» компонентам для визуализации.
- Тестирование в дочерних компонентах не поможет, так как они получают вычисленные значения.значения как реквизиты, которые правильно отображают.
Вот тест, с которым я сражаюсь:
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
Если я попытаюсь запустить исключение с помощью этого:
expect(instance.getExerciseCalsForDay).toBe(1501);
toBe () получит "undefined".
Если япопробуйте использовать mount вместо мелкого, все разрывы ада теряются, поскольку я не реализовал фиктивное хранилище и т. д.
ВОПРОС : если не считать копирования метода непосредственно впроверить (и сделать его функцией), как правильно нацелиться на метод, подобный этому, чтобы иметь возможность запуститьБыть против?Это где нырять?Или я пропустил какой-то фундаментальный аспект всего этого?