Как библиотека тестирования React может утверждать дочерние реквизиты и обновления магазина Redux? - PullRequest
2 голосов
/ 27 мая 2020

Я только начал изучать структуру модульного тестирования для своего приложения реакции. Я заблокировал свой выбор на @testing-library/react вместо Enzyme, как это рекомендуется React и помогает писать более надежные тесты. Я также планирую использовать Jest для полноты.

Но прежде чем я смогу продолжить с React Testing Library, я застрял на нескольких вопросах. Может ли кто-нибудь помочь?

Например,

  1. Существует компонент Editor, который обновляет хранилище Redux на основе ввода данных пользователем.
  2. Есть еще один компонент Preview, который считывает значение непосредственно из хранилища.
  3. Существует третий компонент Container, который содержит оба вышеперечисленных компонента, передающих некоторые реквизиты.

Вопросы:

  1. Как проверить, действительно ли пользовательский ввод в компоненте Editor обновляет хранилище?
  2. Как проверить, может ли компонент Preview отображать значение, считываемое из хранилища?
  3. Как проверить, если Компонент Container правильно передает свойства своим дочерним элементам?


Container.jsx

import React from 'react';
import Editor from './Editor';
import Preview from './Preview';

const Container = ({editorType}) => {
  return (
    <div>
      <Editor type={editorType} />
      <Preview />
    </div>
  );
};
export default Container;

Editor.jsx

import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import {setName} from './actions';

const Editor = ({type}) => {
  const name = useSelector(state => state.name);
  const dispatch = useDispatch();

  return (
    <div>
      <h1>Type: {type}</h1>
      <input value={name} onChange={evt => dispatch(setName(evt.target.value))} />
    </div>
  );
};
export default Editor;

Preview.jsx

import React from 'react';
import { useSelector } from 'react-redux';

const Editor = ({type}) => {
  const name = useSelector(state => state.name);

  return (
    <div>
      <h1>Name: {name}</h1>
    </div>
  );
};
export default Preview;

1 Ответ

1 голос
/ 29 мая 2020

Вот как я бы это сделал:

Как проверить, действительно ли пользовательский ввод в компоненте Editor обновляет хранилище?

Глядя на ваш код, редактор не хранилище обновлений, он не вызывает useDispatch. Но, предполагая, что это так, используя https://github.com/reduxjs/redux-mock-store, я бы установил провайдер фиктивного хранилища для компонента в тесте, затем инициировал ввод пользователя и проверил фиктивное хранилище, если было отправлено правильное действие с правильной полезной нагрузкой :

describe('<Editor />', () => {
  let store: MockStoreEnhanced;
  let rtl: RenderResult;

  beforeEach(() => {
    store = mockStore({ /* your store structure */ });

    rtl = render(
      <Provider store={store}>
        <Editor type={...} />
      </Provider>
    );
  });

  test('dispatch action correctly', () => {
    fireEvent.change(rtl.container.querySelector('input'), { target: {value: 'test' } });

    // check actions that were dispatched by change event
    // getActions return an array avec redux actions (type, payload)
    expect(store.getActions()).toEqual(...);
  }
}

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

Как проверить, может ли компонент предварительного просмотра отображать чтение значения из хранилища?

Тот же принцип, настройте свой тест с имитацией хранилища, инициализируйте это хранилище с соответствующим значением и просто проверьте, что компонент отображает то, что находится в хранилище:

describe('<Preview />', () => {
  let store: MockStoreEnhanced;
  let rtl: RenderResult;

   beforeEach(() => {
     store = mockStore({ name: 'This is name from store' });

     rtl = render(
       <Provider store={store}>
         <Preview type={...} />
       </Provider>
     );
   });

   test('displays store content correctly', () => {
     expect(rtl.getByText('This is name from store')).toBeTruthy();
   }
 }

Как проверить, правильно ли компонент контейнера передает реквизиты своим дочерним элементам?

Здесь вы должны вместе протестировать контейнер + предварительный просмотр + редактор и найти что-то визуальное для тестирования (как настоящий пользователь будет воспринимать его), включая реквизиты, переданные Контейнером своим дочерним элементам.

Например, если Preview отображает props.t ype, который поступает из редактора контейнеров Тип реквизитов:

describe('<Container />', () => {
  // mocked store may not be necessary here, depending on your use case
  let store: MockStoreEnhanced;
  let rtl: RenderResult;

   beforeEach(() => {
     store = mockStore({ name: 'This is name from store' });

     rtl = render(
       <Provider store={store}>
         <Container editorType={'toTest'} />
       </Provider>
     );
   });

   test('displays store content correctly', () => {
     // check that 'toTest' exists in DOM because it is rendered by Preview component, a child of Container
     expect(rtl.getByText('toTest')).toBeTruthy();
   }
 }

Подводя итог, мой подход будет следующим:

  • Тестовые действия и редукторы (очень просто тестировать, конечные автоматы , просто тесты Jest)
  • Проверьте, что компоненты отправляют правильные действия с правильной полезной нагрузкой при правильном вводе пользователя
  • Мок-хранилище для настройки соответствующих вариантов использования (значение хранилища инициализации) для компонентов, считывающих данные из хранилища

Для последних 2 пунктов я использую https://github.com/reduxjs/redux-mock-store.

...