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

Я новичок в модульном тестировании, и я провел около 20-30 часов в документах, статьях и видео на YouTube, но до сих пор не могу понять, как этого добиться. В основном я хочу проверить 3 вещи здесь:

  1. Убедитесь, что этот компонент отображает 3 компонента
  2. Протестируйте условный стиль
  3. Протестируйте событие клика

Пока что, во-первых, если я попытаюсь сделать:

import { shallow } from "enzyme";
import React from "react";
import ButtonsComponent, { SchedButton } from "./ButtonsComponent";

it("renders three <MyButton /> components", () => {
  const wrapper = shallow(<ButtonsComponent />);
  expect(wrapper.find(MyButton)).to.have.lengthOf(3);
});

Я получаю следующую ошибку: TypeError: Enzyme::Selector ожидает строку, объект или конструктор компонента

И у меня нет хорошей идеи, как проверить две другие вещи, я видел несколько примеров, но я не понимаю, как адаптировать их к моей конкретной ситуации, поскольку они, похоже, не проверяют именно то, что я м пытаюсь сделать.

Это упрощенная версия моего компонента:

import React from "react";
import styled from "styled-components";

const MyButton = styled.button`
  background: ${props =>
    props.color ? theme.palette.secondary.dark : "#e6e6e6"};
  color: ${props => (props.color ? "white" : "#737373")};
`;

const ButtonsComponent = ({ currentState, updateState }) => {
  const handleClick = event => {
    updateState(event.target.value);
  };

  return (
    <div>
      <MyButton
        value = "Button 1"
        onClick = {handleClick}
        color = {currentState === "Button 1" ? "#1fbd45" : ""}
      >
        Button 1
      </MyButton>
      <MyButton
        value = "Button 2"
        onClick = {handleClick}
        color = {currentState === "Button 2" ? "#1fbd45" : ""}
      >
        Button 2
      </MyButton>

      <MyButton
        value = "Button 3"
        onClick = {handleClick}
        color = {!currentState || currentState === "Button 3" ? "#1fbd45" : ""}
      >
        Button 3
      </MyButton>
    </div>
  );
};

export default ButtonsComponent;

Любая помощь приветствуется, объяснение ELI5 было бы намного больше!

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
3
0
3 064
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Постараюсь максимально подробно ответить на ваши вопросы.

Итак, у вас есть 3 вопроса:

1. Убедитесь, что этот компонент рендерит 3 компонента

Ваш тест был почти правильным. Ошибка заключалась в том, что вы делали: wrapper.find(MyButton) вместо wrapper.find('MyButton'). Чтобы сделать wrapper.find(MyButton), вам нужно сначала импортировать компонент MyButton, поэтому что-то вроде этого должно работать:

import { shallow } from "enzyme";
import React from "react";
import ButtonsComponent, { MyButton } from "./ButtonsComponent";

it("renders three <MyButton /> components", () => {
  const wrapper = shallow(<ButtonsComponent />);
  expect(wrapper.find(MyButton)).to.have.lengthOf(3);
});

Но вы не можете сделать это в своем коде, потому что вы не экспортируете компонент MyButton. Мой совет по этому вопросу заключается в том, что вы должны создать файл для компонента MyButton и еще один файл для компонента ButtonsComponent. В целом гораздо понятнее иметь один компонент в файле, и модульное тестирование также становится понятнее. Тогда вы сможете сделать что-то вроде этого:

import { shallow } from "enzyme";
import React from "react";
import ButtonsComponent from "./ButtonsComponent";
import MyButton from "./MyButton"

it("renders three <MyButton /> components", () => {
  const wrapper = shallow(<ButtonsComponent />);
  expect(wrapper.find(MyButton)).to.have.lengthOf(3);
});

2. Протестируйте условный стиль

Я не знаю, какой механизм тестирования (mocha, jest и т. д.) вы используете, но если бы мне пришлось выбирать один для тестирования приложения React, я бы выбрал Jest (хотя это всего лишь вопрос вкуса). Я предлагаю jest, потому что в нем есть все, что вам нужно, например, шпионы, матчеры и т. д., а также есть несколько дополнительных пакетов, которые сделают вашу жизнь проще, как в этом случае.

Таким образом, чтобы протестировать ваши стилизованные компоненты с помощью jest, вам понадобятся два дополнительных пакета react-test-renderer (который в основном преобразует компоненты React в объект js) и jest-styled-components (который даст вам дополнительный сопоставитель с именем toHaveStyleRule, который очень поможет вам в вашей цели) .

С этими двумя установленными пакетами вы сначала импортируете их:

import renderer from "react-test-renderer";
import "jest-styled-components";

Затем вы преобразуете свой компонент в объект js:

const tree =
  renderer
  .create(<MyButton color = "red">Test</MyButton>)
  .toJSON();

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

expect(tree).toHaveStyleRule("background-color", "red");

3. Протестируйте событие клика

Чтобы протестировать событие клика, вам понадобится шпион. Если вы используете jest, у вас уже есть эта функция, если вы используете mocha, я думаю, вам, вероятно, понадобится дополнительный пакет, такой как sinon или аналогичный.

Шпион позволит вам отслеживать, что происходит с вашей функцией updateState, поэтому, когда вы тестируете событие клика, вы передаете шпионскую функцию как значение свойства updateState. Таким образом, когда вы имитируете нажатие на кнопку, ваш шпион будет вызываться, а затем вы сможете задать ему вопрос, например «вам звонили?», в результате вы сможете проверить, что при нажатии кнопки вы вызовите функцию updateState с ожидаемыми параметрами.

В эта ссылка вы найдете ваш пример (с небольшими изменениями) работающий и с тестами для всего, что вы хотели проверить (не обращайте внимания на место, где появляются зависимости в файле package.json, многие из них должны отображаться как dev, но по какой-то причине, если я это сделаю, это не сработает, вероятно, я делаю что-то неправильно в этом инструменте).

Я надеюсь, что этот ответ поможет вам.

Большое спасибо за подробный ответ. Это на самом деле очень помогло. Да, забыл сказать, что я использовал Jest.

garo 04.06.2019 18:47

Другие вопросы по теме