function App() {
let [ctr, setCtr] = useState(0);
useEffect(() => {
setCtr(1);
}, []);
//<-------------------------put a debugger here, only hit once
return ctr;
}
个字符
目前这个测试失败,因为测试的expect(...)
在useEffect
触发另一个更新之前完成。所以我想在测试中加入一些东西,让它等待另一个更新完成,这样我就可以看到调试器命中两次。我试过:
it("should render 1", () => {
const el = document.createElement("div");
ReactDOM.render(<App />, el);
for (let i = 0; i < 2000; i++) { // add a long loop so it could have a chance for the `useEffect` trigged update finishes
// ...
}
expect(el.innerHTML).toBe("1"); // this fails!
});
型
但是我仍然不能控制js运行时,下一个要执行的作业看起来像expect(el.innerHTML).toBe("1")
在循环结束后立即执行。那么,我是否可以添加一些类似技巧的东西,以便可以看到调试器命中两次,即让useEffect的更新在expect(...)
语句之前执行
2条答案
按热度按时间3zwtqj6y1#
您的测试不会工作,因为您没有等待重新渲染的发生--在
useEffect
调用setCtr
之后,您的测试中没有任何东西可以触发重新渲染。TBH,我甚至不知道这段代码是否真的会渲染DOM来Assert测试。我认为一个更好的方法是使用react-testing-library,它为您提供了测试React组件的工具,而无需尝试重新发明轮子。
下面是一个Code Sandbox设置的
react-testing-library
和一个简单Assert值1
在DOM中。您可以在代码沙盒的Tests
选项卡中运行测试。下面是相关的代码片段。个字符
希望这对你有帮助!
更新:解决OP的原始问题
您需要做的就是将您的
render
Package 在act
中,从react-dom/test-utils
。要为Assert准备组件,请在act()调用中 Package 呈现组件并执行更新的代码。这使您的测试运行更接近React在浏览器中的工作方式。
行动文件
型
也更新了Code Sandbox。结账
__tests__/SO.test.tsx
8ulbf1ek2#
您可能需要
useLayoutEffect
钩子。字符串