cjm*_*cjm 4 settimeout reactjs jestjs enzyme
我正在尝试使用单击处理程序测试自毁组件的卸载。单击处理程序使用 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"
>
×
</button>
</div>
</section>
) : null}
</>
);
Run Code Online (Sandbox Code Playgroud)
};
导出默认的 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);
});
Run Code Online (Sandbox Code Playgroud)
请注意,我正在用实际模拟 useState 实现,因为在其他测试中我使用了自定义 useState 模拟。
Eri*_*rel 11
不使用酶,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();
});
Run Code Online (Sandbox Code Playgroud)
我直接运行计时器,但按时间推进应该会给出类似的结果。
| 归档时间: |
|
| 查看次数: |
3758 次 |
| 最近记录: |