#javascript #reactjs #unit-testing #jestjs #enzyme
#javascript #reactjs #модульное тестирование #jestjs #enzyme
Вопрос:
Я пытаюсь протестировать следующий компонент:
import React, { Component } from 'react';
import { connect } from 'react-redux'
import moment from 'moment'
import { SingleDatePicker } from 'react-dates'
import MealList from './MealList';
import { capitalize } from '../helpers/helpers'
export class MealSummary extends Component {
state = {
date: moment(),
calendarFocused: false
}
onDateChange = date => {
if (date) this.setState({ date })
}
onFocusChange = ({ focused }) => this.setState({ calendarFocused: focused })
renderMealCategory = (mealCategory) => {
return this.props.meals.filter(meal => meal.mealCategory === mealCategory amp;amp; meal.date.isSame(this.state.date, 'day'))
}
renderFilteredTotal = (mealCategory) => {
return this.props.meals.filter(meal => meal.mealCategory === mealCategory amp;amp; meal.date.isSame(this.state.date, 'day'))
.reduce((sum, n) => sum n.calories, 0)
}
renderTotal = () => (this.props.meals.filter(meal => meal.date.isSame(this.state.date, 'day')).reduce((sum, n) => sum n.calories, 0))
renderMeals = () => {
const categories = ['breakfast', 'lunch', 'dinner', 'snack']
return categories.map(category => {
return (
<div key={category}>
<h1>{capitalize(category)}</h1>
<MealList meals={this.renderMealCategory(category)} />
<h4>Total: {this.renderFilteredTotal(category)}</h4>
</div>
)
})
}
render() {
return (
<div>
<h1>Summary Page</h1>
<SingleDatePicker
date={this.state.date}
onDateChange={this.onDateChange}
focused={this.state.calendarFocused}
onFocusChange={this.onFocusChange}
numberOfMonths={1}
isOutsideRange={() => false}
id="caloriEat-meal-summary" />
{this.renderMeals()}
<div>
<h1>Total Calories Consumed: {this.renderTotal()}</h1>
</div>
</div>
);
}
}
const mapStateToProps = (state) => ({
meals: state.meals
})
export default connect(mapStateToProps)(MealSummary)
Я написал следующий неудачный тест:
import React from 'react';
import { shallow } from 'enzyme'
import { MealSummary } from '../../components/MealSummary'
import { meals } from '../fixtures/mealReducer'
describe('<MealSummary />', () => {
test('should render MealSummary', () => {
const renderMealCategory = jest.fn()
const wrapper = shallow(<MealSummary meals={meals} />)
expect(wrapper).toMatchSnapshot()
})
})
Я получаю сообщение об ошибке:
TypeError: meal.date.isSame is not a function
17 |
18 | renderMealCategory = (mealCategory) => {
> 19 | return this.props.meals.filter(meal => meal.mealCategory === mealCategory amp;amp; meal.date.isSame(this.state.date, 'day'))
| ^
20 | }
21 |
22 | renderFilteredTotal = (mealCategory) => {
Объект meals обладает meals.date
свойством, для которого вызывается метод moment isSame
для сравнения даты в пределах состояния. У меня есть довольно много таких функций в отдельных вызовах для корректного рендеринга страницы. Почему функция не распознается? Я попытался передать фиктивную функцию для isSame
const isSame = jest.fn()
и передал ее в качестве поддержки MealSummary, но это не сработало. Как я могу заставить этот тест корректно работать с методом, который выполняется из другой библиотеки (moment), чтобы я мог заставить его создать снимок?
Ответ №1:
Вы передаете meals
из import { meals } from '../fixtures/mealReducer'
, нам нужно было бы посмотреть, что находится в редукторе, но я предполагаю, что у вас есть что-то вроде:
const meals = [{ mealCategory: 'breakfast', date: new Date()}]
когда вы должны иметь
const meals = [{ mealCategory: 'breakfast', date: moment()}]
Комментарии:
1. У меня есть ссылка на репозиторий github.com/altafmquadri/caloriEat/blob/master/src/tests /…
2. Дата сохраняется в виде строки moment
date: '2020-08-17T18:36:13.173Z',
3. поэтому измените его на
date: moment('2020-08-17T18:36:13.173Z'),
4. или сохраните его и измените компонент, чтобы сделать
moment(meal.date).isSame
5. уточняющий параметр необязателен —
isSame(someDate)
проверит, все ли совпадает (год, месяц, день, час, минута, секунда и т.д.),isSame(someDate, 'day')
проверит, все ли совпадает >= day (то есть, тот же год, месяц и день). Это просто зависит от того, что вы считаете «тем же», что вы должны использовать.