我正在尝试使用jest
和@testing-library/react
来验证react组件(它包装了HTML输入
元素)正在使用正确的值调用它的 onChange
回调以响应 ChangeEvent。
这是 react 组件
export const MyInput = ({ onChange, value }) => {
const handleChange = (event) => {
console.log(event.target.value);
onChange(event);
};
return (
<div>
<input
type="text"
onChange={handleChange}
label={"test-component"}
data-testid={"test"}
value={value}
/>
</div>
);
};
这是测试
test("onChange should work", () => {
const onChangeMock = jest.fn();
let inputValue = 1;
const { getByTestId } = render(
<MyInput onChange={onChangeMock} value={inputValue} />
);
const input = getByTestId("test");
fireEvent.change(input, { target: { value: "23" } });
expect(onChangeMock).toHaveBeenCalled();
expect(onChangeMock).toHaveBeenCalledWith(
expect.objectContaining({
target: expect.objectContaining({
value: "23"
})
})
);
});
这是一个 link to a codesandbox这重现了问题。
我的测试中的第二个断言失败了,因为 onChangeMock
的调用者是一个“target.value
”等于 1
的事件,而不是 23
。
更奇怪的是,当在 handleChange
函数中记录 event.target.value
时 - 它具有正确的值 23
。使用调试器进行检查还表明,jest 模拟具有正确的调用方(目标值为 23
的事件,直到调试器离开 handleChange
函数的范围)。当我返回测试范围并执行断言时,模拟事件的目标值为 1。
所以我试图理解为什么我会观察到这种行为以及造成这种行为的原因是什么?
(我假设事件处理程序作用域结束时,事件的目标被设置(通过什么?)到我的 html 输入元素,并且 jest 不会捕获事件的深度克隆,因为它被传递了到外部函数,但我找不到任何文档来支持这一点)
最佳答案
React 使用 synthetic events与 native DOM 事件不同,它们的行为类似但不完全相同,执行处理程序后合成事件将无效,例如,请使用代码中的事件处理程序尝试此操作:
const handleChange = (event) => {
console.log(event.target.value);
onChange(event); // 23
setTimeout(() => {
console.log(event.target.value);
}, 3000); // 1
};
关于javascript - Jest 捕获输入更改事件并验证在受控 react 组件上使用正确的值调用它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76733190/