У меня есть обработчик onChange на входе, который я пытаюсь протестировать на основе того, что я прочитал в документации Dom Testing Library здесь и здесь .
Одно из различий в моем коде состоит в том, что вместо использования локального состояния для управления входным значением я использую реквизиты.Таким образом, функция onChange фактически вызывает другую функцию (также полученную через реквизиты), которая обновляет состояние, которое было «поднято», для другого компонента.В конечном счете, значение для ввода принимается компонентом в виде реквизита, а значение ввода обновляется.
Я издеваюсь над реквизитом и пытаюсь выполнить несколько простых тестов, чтобы доказать, что обработчик onChange работаеткак и ожидалось.
Я ожидаю, что функция, вызываемая в обработчике изменений, будет вызываться столько же раз, сколько fireEvent.change используется в тесте, и это работает с:
const { input } = setup();
fireEvent.change(input, { target: { value: "" } });
expect(handleInstantSearchInputChange).toHaveBeenCalledTimes(1);
Я ожидаю, что input.value читается из исходной настройки mock prop, и это работает с:
const { input } = setup();
expect(input.value).toBe("bacon");
Однако, Я делаю что-то глупое (не понимаю mockкажется, что он вообще функционирует), и я не могу понять, почему следующий блок не обновляет input.value и продолжает читать настройку input.value из исходной настройки mock prop.
Это терпит неудачу с ожиданием "" / полученный "бекон" <= установленный в оригинальной пропеGED, учитывая код ниже?Я предполагаю, что мне нужна функция mock <em>handleInstantSearchInputChange , чтобы что-то сделать, но я пока не совсем понимаю, что я здесь делаю.
Спасибо за любой совет, как это сделать и/ или лучше понять это.
Тестовый файл
import React from "react";
import InstantSearchForm from "../../components/InstantSearchForm";
import { render, cleanup, fireEvent } from "react-testing-library";
afterEach(cleanup);
let handleInstantSearchInputChange, props;
handleInstantSearchInputChange = jest.fn();
props = {
foodSearch: "bacon",
handleInstantSearchInputChange: handleInstantSearchInputChange
};
const setup = () => {
const utils = render(<InstantSearchForm {...props} />);
const input = utils.getByLabelText("food-search-input");
return {
input,
...utils
};
};
it("should render InstantSearchForm correctly with provided foodSearch prop", () => {
const { input } = setup();
expect(input.value).toBe("bacon");
});
it("should handle change", () => {
const { input } = setup();
fireEvent.change(input, { target: { value: "" } });
expect(input.value).toBe("");
fireEvent.change(input, { target: { value: "snickerdoodle" } });
expect(input.value).toBe("snickerdoodle");
});
Компонент
import React from "react";
import PropTypes from "prop-types";
const InstantSearchForm = props => {
const handleChange = e => {
props.handleInstantSearchInputChange(e.target.value);
};
return (
<div className="form-group">
<label className="col-form-label col-form-label-lg" htmlFor="food-search">
What did you eat, fatty?
</label>
<input
aria-label="food-search-input"
className="form-control form-control-lg"
onChange={handleChange}
placeholder="e.g. i ate bacon and eggs for breakfast with a glass of whole milk."
type="text"
value={props.foodSearch}
/>
</div>
);
};
InstantSearchForm.propTypes = {
foodSearch: PropTypes.string.isRequired,
handleInstantSearchInputChange: PropTypes.func.isRequired
};
export default InstantSearchForm;