Проверьте, что метод React prop был вызван с помощью Jest
У меня есть компонент Input, который принимает метод prop и вызывает его, когда пользователь что-то вводит. Сам код работает как положено, но по некоторым причинам тест не проходит. Он считает, что метод поддержки не был вызван. Почему это происходит? В целях тестирования я использую Jest и реагировать на тестирование библиотеки.
И второй вопрос. В реальном приложении моя идея состоит в том, чтобы проверить параметры, которые были переданы этому методу проп. Считается ли это тестированием реализации (я знаю, что должен его протестировать)?
Input.js
export default function Input({ onChange }) {
return <input onChange={onChange} />;
}
Тестовое задание
import React from "react";
import { render, act, cleanup, fireEvent } from "react-testing-library";
import Input from "./input";
describe("Input tests", () => {
afterEach(cleanup);
it("Should call prop function", () => {
const onChange = jest.fn();
const { getByTestId } = render(<Input onChange={onChange} />);
const input = getByTestId("input");
act(() => {
fireEvent.change(input, { target: { value: "Q" } });
});
expect(onChange).toHaveBeenCalled();
});
});
1 ответ
После прочтения это выглядит так, как будто не предназначено для защиты от обработчиков событий. Хотя, похоже, что он работает в React 16.5, использовать 16.8.x не удается. Я бы посоветовал перейти на энзим, если вы хотите проверить такие функции.
Тестирование с react-testing-library
терпит неудачу (однако, как вы заметите, при запуске теста значение входных данных действительно изменится): https://codesandbox.io/s/n3rvy891n4
Тестирование с enzyme
успешно: https://codesandbox.io/s/lx34ny41nl
Причина, по которой ваш тест не работает, заключается в том, что вы используете getByTestId
найти свой элемент. getByTestId
ищет DOM-узел, который имеет data-testid
приписывать.
Для того, чтобы пройти тест, у вас есть различные варианты.
Вы можете добавить data-testid
на ваш input
: <input data-testid="input" onChange={onChange} />
, Это сработало бы, однако лучше избегать тестовых идентификаторов, когда это возможно.
В реальном приложении ваш вклад будет отображаться с label
мы можем воспользоваться этим:
const { getByLabelText } = render(
<label>
My input
<Input onChange={onChange} />
</label>
)
const input = getByLabelText('My input')
Другое решение заключается в использовании container
который является одним из значений, возвращаемых render
, Это узел DOM, как и все остальное в RTL, поэтому вы можете использовать обычные API DOM:
const { container } = render(<Input onChange={onChange} />)
// Any of these would work
const input = container.firstChild
const input = container.querySelector('input')
В качестве примечания, я согласен, что RTL тесты кажутся более сложными по сравнению с Enzyme. Для этого есть веская причина. RTL подталкивает вас к тестированию вашего приложения, как если бы оно было черным ящиком. Это немного сложнее сделать в начале, но в конечном итоге приводит к лучшим тестам.
Фермент, с другой стороны, по умолчанию высмеивает большинство вещей и позволяет вам взаимодействовать с вашими компонентами реализации. По моему опыту, это выглядит проще в начале, но даст хрупкие испытания.
Я призываю вас присоединиться к каналу спектра, если вам нужна помощь для начала работы.