我尝试使用jest
和@testing-library/react
来验证react组件(* Package 了HTML input
元素 *)正在调用它的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,它再现了这个问题。
我的测试中的第二个Assert失败了,因为onChangeMock
的调用者是一个事件,其' target.value
等于1
,而不是23
。
更奇怪的是,当在handleChange
函数中记录event.target.value
时,它具有正确的值23
。使用调试器进行检查还显示jest mock有一个正确的调用者(目标值为23
的事件,直到调试器离开handleChange
函数的作用域)。当我回到测试范围并执行Assert时,mock的事件的目标值为1。
所以我试图理解为什么我会观察到这种行为,是什么导致了它?
- (我假设事件的目标已经设定好了(但是通过什么?)在事件处理程序作用域结束的那一刻,jest没有捕获事件的深层克隆,因为它被传递给了外部函数,但我找不到任何文档来支持这一点)*
2条答案
按热度按时间dohp0rv51#
React使用合成事件而不是原生DOM事件,它们的行为相似但不完全相同,合成事件在处理程序处理程序执行后无效,为了说明,请尝试使用您代码中的事件处理程序:
字符串
gmxoilav2#
您的文本输入不会影响更改,因为您的代码没有将其视为受控输入。
简而言之,测试期待正确的事情,但是组件忽略了变化。
试试这个:
字符串
您将在Testing Library InputEvent docs中看到一个类似的示例