我在输入上有一个 onChange 处理程序,我正在尝试根据我在 Dom 测试库文档here和here中阅读的内容进行测试。
我的代码中的一个区别是,我使用的是道具,而不是使用本地状态来控制输入值。所以 onChange 函数实际上是在调用另一个函数(也是通过 props 接收的),它将已经“提升”到另一个组件的状态更新。最终,输入的值作为 prop 被组件接收并更新输入值。
我在嘲笑道具并尝试做一些简单的测试来证明 onChange 处理程序按预期工作。
我希望在更改处理程序中调用的函数被调用的次数与测试中使用 fireEvent.change 的次数相同,这适用于:
const { input } = setup();
fireEvent.change(input, { target: { value: "" } });
expect(handleInstantSearchInputChange).toHaveBeenCalledTimes(1);
我希望从原始模拟道具设置中读取 input.value ,这适用于:
const { input } = setup();
expect(input.value).toBe("bacon");
但是,我在做一些愚蠢的事情(似乎根本不理解模拟函数),我无法弄清楚为什么下面的块不更新 input.value,并继续从原始的模拟道具设置。
这失败了,期待“”/收到“培根”<=在原始道具中设置
fireEvent.change(input, { target: { value: "" } });
expect(input.value).toBe("");
问题:如何编写测试来证明 input.value 已根据以下代码更改?我假设我需要模拟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;