首页 > 解决方案 > 无法编写在渲染中调用 moment 方法的组件的快照测试

问题描述

我正在尝试测试以下组件:

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 && meal.date.isSame(this.state.date, 'day'))
    }

    renderFilteredTotal = (mealCategory) => {
        return this.props.meals.filter(meal => meal.mealCategory === mealCategory && 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 && meal.date.isSame(this.state.date, 'day'))
         |                                                                                                ^
      20 |     }
      21 | 
      22 |     renderFilteredTotal = (mealCategory) => {

对象餐有一个meals.date属性,调用该属性的时刻方法isSame来比较状态内的日期。我在单独的调用中有很多这样的函数来正确呈现页面。为什么无法识别该功能?我尝试传递一个模拟函数isSame const isSame = jest.fn()并将其作为道具传递给 MealSummary,但它不起作用。如何使用从不同(时刻)库运行的方法使该测试正常工作,以便我可以让它创建快照?

标签: javascriptreactjsunit-testingjestjsenzyme

解决方案


meals从传入import { meals } from '../fixtures/mealReducer',我们需要看看减速器中有什么,但我猜你有类似的东西:

const meals = [{ mealCategory: 'breakfast', date: new Date()}]

当你应该有

const meals = [{ mealCategory: 'breakfast', date: moment()}]

推荐阅读