这里是一个代码沙箱,其中包含一个模拟此问题的测试。如以下问题中所述,此代码沙箱中的测试失败:https://codesandbox.io/s/react-jest-and-enzyme-testing-c7vng
我正在尝试测试在<input />
内部更新的useEffect
的值。这是代码沙箱中的代码,它是我在项目中尝试做的事情的简化版本。
import React, { useEffect, useRef, useState } from "react";
const App = () => {
const [count, setCount] = useState(0);
useEffect(() => {
ref.current.value = "";
console.log(typeof ref.current.value);
}, [count]);
const ref = useRef(null);
const handleClick = () => {
setCount(count + 1);
console.log(count);
};
return (
<div>
<input ref={ref} type="text" />
<button onClick={handleClick}>click me</button>
</div>
);
};
export default App;
我使用useRef
设置<input />
的值。
单击useEffect
时将调用<button />
。 <button />
更新useState
count
。 useEffect
正在观看count
的更新,并且被称为副作用。
在useEffect
中,我将ref.current.value
设置为一个空字符串,然后将typeof
这个值记录下来以验证它是一个字符串。
在测试中,我尝试模拟这种行为:
describe("App", () => {
const wrapper = mount(<App />);
wrapper.find("input").props().value = "hello";
act(() =>
wrapper
.find("button")
.props()
.onClick()
);
console.log(wrapper.find("input").debug());
wrapper.update();
console.log(wrapper.find("input").debug());
expect(wrapper.find("input").length).toBe(1);
expect(wrapper.find("input").props().value).toBe("hello");
});
我将value
属性设置为'hello'
。然后,我调用<button />
onClick
道具,并有效地单击它。然后,我调用wrapper.update()
,并且在debug()
之前和之后也将<input />
记录为update()
。
update()
之前,<input />
具有包含value
的'hello'
道具。在update()
之后,<input />
没有value
属性。这会导致测试失败,表示更新后<input />
value
未定义。
更新后输入的值不是''
吗?
以下是当前方式的问题列表:
[<input ref={ref} type="text" />
描述一个React Element,没有值prop
属性值应通过状态控制,而不是直接变异
wrapper.find("input").props().value = "hello";
在DOM节点上设置值与设置prop值不同。使用React意味着您要对它进行DOM操作。当传递useRef
的初始值时,null
允许访问基础DOM节点,并且尽管App
状态,此下一行仍会更改DOM。
ref.current.value = "";
在某些情况下,尽管处于App状态,但还是很方便地操作DOM。然后,测试应处理DOM节点并对其进行更改。
describe("App", () => {
const wrapper = mount(<App />);
wrapper.find("input").getDOMNode().value = "hello";
act(() =>
wrapper
.find("button")
.props()
.onClick()
);
wrapper.update();
expect(wrapper.find("input").length).toBe(1);
expect(wrapper.find("input").getDOMNode().value).toBe("");
});