Как проверить функцию, переданную из mapDispatchToProps (React / Redux / Enzyme / Jest) - PullRequest
0 голосов
/ 29 августа 2018

Я хочу проверить, что функция, переданная из mapDispatchToProps, была вызвана при симуляции нажатия кнопки.

Как протестировать ту функцию, которая была передана из mapDispatchToProps?

Я пытался передать поддельную функцию реквизитом, но она не работает. Любая помощь будет оценена.

Здесь ниже мой поддельный код класса и тестовый пример.

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

// All required imports

class App extends React.Component<Props> {
  render() {
    const { onClick } = this.props;
    return (
      <>
        <h1>Form</h1>
        <input />
        <button onClick={() => onClick()} />
      </>
    );
  }
}

const mapStateToProps = (state) => {
  return {
    state
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    onClick: () => dispatch(actions.onClick())
  };
};

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

Мой тестовый файл

import { configure, mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16/build/index';
import jsdom from 'jsdom';
import React from 'react';
import { Provider } from 'react-redux';
import configureMockStore from 'redux-mock-store';
import ConnectedApp, { App } from './App';

function setUpDomEnvironment() {
  const { JSDOM } = jsdom;
  const dom = new JSDOM('<!doctype html><html><body></body></html>', { url: 'http://localhost/' });
  const { window } = dom;
  global.window = window;
  global.document = window.document;
  global.navigator = {
    userAgent: 'node.js',
  };
  copyProps(window, global);
}

function copyProps(src, target) {
  const props = Object.getOwnPropertyNames(src)
    .filter(prop => typeof target[prop] === 'undefined')
    .map(prop => Object.getOwnPropertyDescriptor(src, prop));
  Object.defineProperties(target, props);
}

setUpDomEnvironment();

configure({ adapter: new Adapter() });


const mockStore = configureMockStore();

describe('App', () => {
  describe('When App connected to store', () => {
    describe('When button clicked', () => {
      it('should not crush after click on login button', () => {
      const onClick = jest.fn()
        const store = mockStore(initialStates[1]);
        const wrapper = mount(
          <Provider store={store}>
            <ConnectedApp />
          </Provider>);
        wrapper.find('button').simulate('click');
        ??? how to test that function passed from mapDispatchToProps was fired?
      });
    });
  });
});

1 Ответ

0 голосов
/ 29 августа 2018

Я рекомендую следовать подходу, описанному в документации , и экспортировать подключенный компонент как экспорт default для использования в приложении, а также экспортировать сам компонент как именованный экспорт для тестирования.

Для кода выше export класс App и проверка клика следующим образом:

import * as React from 'react';
import { shallow } from 'enzyme';
import { App } from './code';

describe('App', () => {

  it('should call props.onClick() when button is clicked', () => {
    const onClick = jest.fn();
    const wrapper = shallow(<App onClick={onClick} />);
    wrapper.find('button').simulate('click');
    expect(onClick).toHaveBeenCalledTimes(1);
  });

});

shallow предоставляет все необходимое для тестирования самого компонента. (shallow даже вызывает методы жизненного цикла React с Enzyme v3)

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

Я считаю, что гораздо эффективнее напрямую протестировать компонент, а также экспортировать и напрямую тестировать mapStateToProps() и mapDispatchToProps(), что очень просто, поскольку они должны быть чистыми функциями .

mapDispatchToProps() в приведенном выше коде можно проверить следующим образом:

describe('mapDispatchToProps', () => {
  it('should dispatch actions.onClick() when onClick() is called', () => {
    const dispatch = jest.fn();
    const props = mapDispatchToProps(dispatch);
    props.onClick();
    expect(dispatch).toHaveBeenCalledWith(actions.onClick());
  });
});

Этот подход делает модульное тестирование компонента очень простым, поскольку вы можете напрямую передавать реквизиты компонента, и очень просто проверить, что компоненту будут переданы правильные реквизиты чистыми функциями ( или объектами ). ) передано connect().

Это гарантирует, что модульные тесты просты и целенаправленны. Проверка того, что connect() и redux работают правильно с компонентом, и все его дочерние компоненты при полной визуализации DOM могут быть выполнены в тестах e2e.

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