Я новичок в модульном тестировании, и я провел около 20-30 часов в документах, статьях и видео на YouTube, но до сих пор не могу понять, как этого добиться. В основном я хочу проверить 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 было бы намного больше!
Постараюсь максимально подробно ответить на ваши вопросы.
Итак, у вас есть 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.