Material-UI withStyles компоненты не будут отображаться при тестировании с Enzyme + Jest - PullRequest
1 голос
/ 10 октября 2019

Я пытаюсь проверить компонент. Тест работал без стилизации, но теперь, когда я разработал его с помощью Material-UI, тест больше не работает. Кажется, что компонент, если стилизованный с Material-UI будет отображаться только как [object Object] (не определено).

У меня есть форма, которую я экспортирую как: export default withStyles(styles)(ShuttleForm);

Но я могупротестируйте компонент ShuttleForm или любой компонент, который его использует, теперь, когда я экспортирую его со стилями.

Как я могу протестировать стилизованный компонент material-ui? Я просмотрел документацию для материалов и использовал их createShallow, но это не имело значения.

Это мой тестовый файл:

import React from 'react';
import { createShallow } from '@material-ui/core/test-utils';
import { AddShuttlePage } from '../../components/AddShuttlePage';
import shuttles from '../fixtures/shuttles';

let addShuttle, history, shallow, wrapper;

beforeEach(() => {
  addShuttle = jest.fn();
  history = { push: jest.fn() };
  shallow = createShallow();
  wrapper = shallow(<AddShuttlePage addShuttle={addShuttle} history={history} />)
});

test('should render AddShuttlePage correctly', () => {
  expect(wrapper).toMatchSnapshot();
});

test('should handle onSubmit', () => {
  wrapper.find('ShuttleForm').prop('onSubmit')(shuttles[1]);
  expect(history.push).toHaveBeenLastCalledWith('/');
  expect(addShuttle).toHaveBeenLastCalledWith(shuttles[1]);
});

Этопродолжает падать на wrapper.find('ShuttleForm').prop... с помощью метода «props», предназначенного для запуска только на одном узле. Вместо этого найдено 0.

Мой компонент:

import React from 'react';
import { connect } from 'react-redux';
import ShuttleForm from './ShuttleForm';
import { addShuttle } from '../actions/shuttles';

export class AddShuttlePage extends React.Component {
  onSubmit = (shuttle) => {
    this.props.addShuttle(shuttle);
    this.props.history.push('/');
  };
  render() {
    return (
      <div>
        <h1>Add Shuttle</h1>
        <ShuttleForm
          onSubmit={this.onSubmit}
        />
      </div>
    );
  }
}

const mapDispatchToProps = (dispatch) => ({
  addShuttle: (shuttle) => dispatch(addShuttle(shuttle))
});

export default connect(undefined, mapDispatchToProps)(AddShuttlePage);

Компонент, вызывающий проблемы:

import React from 'react';
import PropTypes from 'prop-types';
import moment from 'moment';
import 'react-dates/initialize';
import 'date-fns';
import DateFnsUtils from '@date-io/date-fns';
import { MuiPickersUtilsProvider, 
         KeyboardTimePicker,
         KeyboardDatePicker 
       } from '@material-ui/pickers';
import { withStyles } from '@material-ui/core/styles';
import InputLabel from '@material-ui/core/InputLabel';
import MenuItem from '@material-ui/core/MenuItem';
import FormControl from '@material-ui/core/FormControl';
import Select from '@material-ui/core/Select';
import Button from '@material-ui/core/Button';
import TextField from '@material-ui/core/TextField';

const styles = theme => ({
  root: {
    display: 'flex',
    flexWrap: 'wrap',
  },
  formControl: {
    margin: theme.spacing(1),
    minWidth: 120,
  },
  selectEmpty: {
    marginTop: theme.spacing(2),
  },
  button: {
    margin: theme.spacing(1),
  },
  textField: {
    marginLeft: theme.spacing(1),
    marginRight: theme.spacing(1),
    width: 200,
  },
});

export class ShuttleForm extends React.Component {
  constructor(props) {
    super(props);

    this.state ={
      origin: props.shuttle ? props.shuttle.origin : '',
      destination: props.shuttle ? props.shuttle.destination : '',
      date: props.shuttle ? moment(props.shuttle.date) : moment(),
      time: props.shuttle ? props.shuttle.time : moment(),
      spots: props.shuttle ? props.shuttle.spots : '',
      cost: props.shuttle ? props.shuttle.cost : '',
      error: ''
    }
  }
  onOriginChange = (e) => {
    const origin = e.target.value;
    this.setState(() => ({ origin }));
  };
  onDestinationChange = (e) => {
    const destination = e.target.value;
    this.setState(() => ({ destination }));
  };
  onDateChange = (date) => {
    if (date) {
      this.setState(() => ({ date }));
    }
  };
  onFocusChange = ({ focused }) => {
    this.setState(() => ({ calendarFocused: focused }));
  };
  onTimeChange = (time) => {
    console.log('time',time);
    if (time) {
      this.setState(() => ({ time }));
    }
  };
  onSpotsChange = (e) => {
    const spots = e.target.value;
    this.setState(() => ({ spots }));
  };
  onCostChange = (e) => {
    const cost = e.target.value;
    this.setState(() => ({ cost }));
  };

  onSubmit = (e) => {
    e.preventDefault();

    if (!this.state.origin || !this.state.destination) {
      this.setState(() => ({ error: 'Please provide origin and destination.' }));
    } else {
      this.setState(() => ({ error: '' }));
      this.props.onSubmit({
        origin: this.state.origin,
        destination: this.state.destination,
        date: this.state.date.valueOf(),
        time: this.state.time.valueOf(),
        spots: e.target.elements.spots.value.trim(),
        cost: e.target.elements.cost.value.trim(),
      });
    }
  }

  render() {
    const { classes } = this.props;
    return (
      <MuiPickersUtilsProvider utils={DateFnsUtils}>
        <div>
          {this.state.error && <p>{this.state.error}</p>}
          <form className={classes.root} onSubmit={this.onSubmit}>
            <FormControl className={classes.formControl}>
              ***Form is here but I have removed it for brevity***
            <Button variant="contained" className={classes.button} type="submit">Add Shuttle</Button>
          </form>
        </div>
      </MuiPickersUtilsProvider>
    );
  }
}

ShuttleForm.propTypes = {
  classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(ShuttleForm);

1 Ответ

0 голосов
/ 11 октября 2019

Поскольку вы оборачиваете компонент в HOC, вам нужно погрузиться в него, чтобы получить доступ к вашему внутреннему компоненту за пределами HOC. Это может быть установлено при вызове createShallow:

beforeEach(() => {
  addShuttle = jest.fn();
  history = { push: jest.fn() };
  shallow = createShallow({ dive: true });
  wrapper = shallow(<AddShuttlePage addShuttle={addShuttle} history={history} />)
});
...