gpt4 book ai didi

reactjs - 使用 setTimeout 进行 Jest 测试 Hook 状态更新

转载 作者:行者123 更新时间:2023-12-03 21:15:57 25 4
gpt4 key购买 nike

我正在尝试使用单击处理程序测试自毁组件的卸载。单击处理程序使用 setTimeout 更新 useState。

但是,我的测试失败了,而我希望它通过。我尝试使用玩笑模拟计时器,例如 AdvanceTimersByTime() 但它不起作用。如果我在 setTimeout 之外调用 setState,则测试通过。

组件.js

const DangerMsg = ({ duration, onAnimDurationEnd, children }) => {
const [isVisible, setVisible] = useState(false);
const [sectionClass, setSectionClass] = useState(classes.container);

function handleAnimation() {
setSectionClass(classes.containerAnimated);
let timer = setTimeout(() => {
setVisible(false);
}, 300);
return clearTimeout(timer);
}

useEffect(() => {
let timer1;
let timer2;
function animate() {
if (onAnimDurationEnd) {
setSectionClass(classes.containerAnimated);
timer2 = setTimeout(() => {
setVisible(false);
}, 300);
} else {
setVisible(false);
}
}

if (children) {
setVisible(true);
}
if (duration) {
timer1 = setTimeout(() => {
animate();
}, duration);
}
return () => {
clearTimeout(timer1);
clearTimeout(timer2);
};
}, [children, duration, onAnimDurationEnd]);

return (
<>
{isVisible ? (
<section className={sectionClass} data-test="danger-msg">
<div className={classes.inner}>
{children}
<button
className={classes.btn}
onClick={() => handleAnimation()}
data-test="btn"
>
&times;
</button>
</div>
</section>
) : null}
</>
);

};

导出默认的 DangerMsg;

测试.js
it("should NOT render on click", async () => {
jest.useFakeTimers();
const { useState } = jest.requireActual("react");
useStateMock.mockImplementation(useState);
// useEffect not called on shallow
component = mount(
<DangerMsg>
<div></div>
</DangerMsg>
);
const btn = findByTestAttr(component, "btn");
btn.simulate("click");
jest.advanceTimersByTime(400);
const wrapper = findByTestAttr(component, "danger-msg");
expect(wrapper).toHaveLength(0);
});

注意 ,我用实际来模拟 useState 实现,因为在其他测试中我使用了自定义 useState 模拟。

最佳答案

不使用 enzyme ,而是使用 testing-library/react,所以这是一个部分解决方案。以下测试按预期通过:

  test("display loader after 1 second", () => {
jest.useFakeTimers(); // mock timers
const { queryByRole } = render(
<AssetsMap {...defaultProps} isLoading={true} />
);
act(() => {
jest.runAllTimers(); // trigger setTimeout
});
const loader = queryByRole("progressbar");
expect(loader).toBeTruthy();
});

我直接运行计时器,但按时间推进应该会给出类似的结果。

关于reactjs - 使用 setTimeout 进行 Jest 测试 Hook 状态更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60688975/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com