Функция-обработчик клика не вызывается - PullRequest
0 голосов
/ 11 июня 2018

Компонент, который я хочу протестировать:

import React from 'react';
import { connect } from 'react-redux';
import { actionCreators as calculatorActionCreators } from './calculator';

class Pad extends React.Component {
  handleClick = () => {
    this.props.add(this.props.value);
  };
  render() {
    return (
      <div className="pad" onClick={this.handleClick}>
        {this.props.display}
      </div>
    );
  }
}

const mapStateToProps = state => ({});
const mapDispatchToProps = dispatch => ({
  add: val => dispatch(calculatorActionCreators.addExpression(val)),
});

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Pad);

Тест:

import React from 'react';
import store from './store';
import Enzyme, { mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

import Pad from './Pad';
it('adds calculation steps', () => {
  const mockAdd = jest.fn();
  const value = 1;
  const element = mount(
    <Pad
      store={store}
      value={value}
      add={mockAdd}
    />
  );
  const clickable = element.find('.pad');
  clickable.simulate('click');
  expect(mockAdd).toHaveBeenCalledWith(value);
});

Я ожидаю, что имитированный щелчок по элементу .pad вызовет handleClick, итаким образом this.props.add будет вызван.Но когда я запускаю тест, я получаю эту ошибку:

Ожидаемая фиктивная функция, которая будет вызвана с: [1]

Но она не была вызвана

Приложение работает, когда я тестирую приложение вручную, поэтому, я думаю, что-то не так с тем, как я пытаюсь его протестировать.

РЕДАКТИРОВАТЬ: Я узнал, как я могу сделатьпроход теста: в Pad.js также экспортируйте развернутый компонент:

export class UnwrappedPad extends React.Component {
    ...
}
...
export default connect(mapStateToProps, mapDispatchToProps)(UnwrappedPad);

И в тесте используйте развернутый компонент вместо подключенного.

Я до сих пор не понимаюпочему он не работает при обёртывании в connect.

1 Ответ

0 голосов
/ 11 июня 2018

Похоже, вы передаете свой обработчик в контейнер, а не в компонент.Всякий раз, когда вы имитируете щелчок, этот метод сопоставляется с реквизитом вашего компонента, который вызывается.

Итак, у вас есть две возможности.

1) Redux помогает вам отделить презентацию от поведения, чтобы вы могли извлечь ваш презентационный компонент и протестировать его отдельно.Ваш тест, вероятно, будет выглядеть примерно так:

it('adds calculation steps', () => {
  const mockAdd = jest.fn();
  const value = 1;
  const element = mount(<Pad value={value} add={mockAdd}/>);
  const clickable = element.find('.pad');

  clickable.simulate('click');

  expect(mockAdd).toHaveBeenCalledWith(value);
});

Ваш компонент будет выглядеть так:

export class Pad extends React.Component {

  handleClick = () => {
    this.props.add(this.props.value);
  };

  render() {
    return (
      <div className="pad" onClick={this.handleClick}>
        {this.props.display}
      </div>
    );
  }
}

2) Если вы действительно хотите протестировать компонент интеграции и контейнер, то вы можетеиспользуйте что-то вроде redux-mock-store .Это позволит вам проверить действие, выполненное через диспетчера.Ваш тест, вероятно, будет выглядеть примерно так:

it('adds calculation steps', () => {
  const mockStore = configureStore([])
  const store = mockStore({})
  const value = 1;
  const element = mount(
    <Provider store={store}>
      <Pad value={value}/>
    </Provider>
  );

  const clickable = element.find('.pad');

  clickable.simulate('click');

  expect(store.getActions()).toHaveBeenCalledWith([
    calculatorActionCreators.addExpression(val),
  ]);
});

Также метод mapStateToProps из redux получает 2-й аргумент, который является собственным портом контейнера.Затем я бы объяснил, что значение передается через.

например, const mapStateToProps = (state, ownProps) => ({ value: ownProps.value});

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...