Ранее мы рассмотрели, как настроить Jest и Enzyme с некоторыми из них, и сделали небольшой обходной путь, чтобы взглянуть на имитацию модулей ES и CommonJS с помощью Jest.

В этом посте мы рассмотрим несколько дополнительных примеров того, как имитировать взаимодействие пользователя с компонентом через Enzyme для создания конкретных тестовых сценариев.

Мы будем использовать mount Enzyme для полного рендеринга DOM, как описано в первой публикации этой серии. Подводя итог, из документации:

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

Если вы не хотите запускать тесты внутри браузера, рекомендуемый подход к использованию mount заключается в использовании библиотеки под названием jsdom, которая, по сути, является безголовым браузером, полностью реализованным на JS.

Это то, что дает нам возможность взаимодействовать с нашим компонентом React, как если бы мы находились внутри браузера.

Приведенные примеры основаны на следующих версиях:

"enzyme": "^3.3.0",
"enzyme-adapter-react-16": "^1.1.1",
"enzyme-to-json": "^3.3.3",

Моделирование событий

Синтаксис фермента для имитации взаимодействия с пользователем легко читается, в простейшем виде, как показано ниже, на смонтированном компоненте:

component.find(selector).simulate(event);

Селекторы

Селекторы могут быть одним из:

  • Селектор CSS
  • Селектор атрибутов реквизита
  • Селектор объектов опоры
  • Конструктор компонентов React
  • React Component displayName

В рассмотренных здесь примерах мы просто рассмотрим синтаксис различных способов нацеливания на селекторы CSS. Документация Enzyme хорошо написана и содержит хорошие примеры, которые стоит продолжить, если селектор CSS не соответствует вашим целям.

Непосредственно из документации мы видим, что поддерживаются:

  • Синтаксис класса (.foo, .foo-bar и т. Д.)
  • Синтаксис элемента (input, div, span и т. Д.)
  • Синтаксис идентификатора (#foo, #foo-bar и т. Д.)
  • Синтаксис атрибута ([href="foo"], [type="text"] и т. Д.)

Возможны комбинации вышеперечисленного (button#id-foo и т. Д.).

Распространенной ошибкой является Method "simulate" is only meant to be run on a single node. 3 found instead., если взаимодействующий подкомпонент используется в родительском компоненте более одного раза.

Это простое исправление, поскольку можно указать индекс узла, с которым вы хотите взаимодействовать:

// the initial
component.find([className="checkbox__input"]).simulate(event);
// becomes
component.find([className="checkbox__input"]).at(1).simulate(event);

События

Simulate Enzyme используется для моделирования событий DOM, наиболее распространенными из которых являются щелчок, изменение и нажатие клавиши. После того, как узел выбран, симуляция привязывается к цепочке, чтобы завершить фиктивное взаимодействие:

component.find(selector).simulate('click');
component.find(selector).simulate('change');
component.find(selector).simulate('keydown', { keyCode: 32 });

Написание тестов

Тестирование повторного рендеринга

Если событие DOM вызывает повторный рендеринг, например размонтирование дочернего компонента, то Тестирование снимков Jest можно использовать для тестирования рендеринга компонента, как ожидалось.

it('should be possible to open menu with Spacebar', done => {
  const component = mount(<MyComponent />);
  component.find('#link-id').simulate('keydown', { keyCode: 32 });
  expect(component).toMatchSnapshot();
  component.unmount();
});

Тестирование вызовов функций

Если функция передается дочернему компоненту, вы можете проверить, правильно ли она вызывается при монтировании родительского компонента. Функция сначала имитируется и передается как правильная опора.

const mockFunction = jest.fn();
it('should call mockFunction on button click', () => {
  const component = mount(
    <MyComponent onClickFunction={mockFunction} />
  );
  component.find('button#ok-btn').simulate('click');
  expect(mockFunction).toHaveBeenCalled();
  
  component.unmount();
});

Состояние тестирования или обновления свойств

Также можно оценить компоненты состояние и реквизит.

it('sets loading state to true on save press', () => {
  const component = mount(<MyComponent />);
  component.find('[className="save-button"]').simulate('click');
  expect(component.state('isLoading')).toEqual(true);
  component.unmount();
});

Другие взаимодействия с документом

Поскольку mount имеет доступ к полной модели DOM, в тесты могут быть включены многие другие аспекты.

Сюда входят куки, связанные с текущим документом. Они доступны через document.cookie. Чтобы изменения не сохранялись между тестами, вы можете использовать что-то вроде

beforeEach(() => {
  document.cookie = '';
});

чтобы сбросить их значения.

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

it('syncs state with user cookie on mount', () => {
  document.cookie = 'cookieOne=valueOne:::false&valueTwo:::true';
  
  const component = mount(<MyComponent />);
  expect(component.state('valueOne')).toEqual(false);
  expect(component.state('valueTwo')).toEqual(true);
  component.unmount();
});

Последние мысли

Надеюсь, это дает представление о возможностях, которые существуют при совместном использовании Jest и Enzyme, а приведенные здесь примеры достаточно удобочитаемы, чтобы использовать части, применимые к вашим собственным проектам.

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

console.log(component.debug())

чтобы увидеть моментальный снимок смонтированного компонента в это время.

Спасибо за чтение, и если у вас есть собственные сообщения, которые расширяют эту тему, не стесняйтесь ссылаться на них в комментариях! 😁

Другие сообщения, которые я написал, включают: