My goal is to test simple component that count down from 60s to 0 and then run a function.
Comonent:
import { useEffect, useState } from "react";
export default function Clock({ dispatch }) {
const [clock, setClock] = useState(60);
useEffect(() => {
const tick = setInterval(() => {
setClock(clock - 1);
}, 1000);
if (clock === 0) {
dispatch({ type: "breakDone" });
}
return function cleanUp() {
clearInterval(tick);
};
});
console.log(clock);
return (
<div className="clock__container">
<h1>{clock}s</h1>
<p data-testid="clock-paragraph">
lorem ipsum
</p>
</div>
);
}
I have a problem with testing component. I have tried to test it with different methods, however my timer have never go down to 59s.
What I have tired:
- Gives the worst feedback -> fake positive
test("Value of clock after 1s", async () => {
render(<Clock />);
expect(screen.getByText("60s")).toBeInTheDocument();
setTimeout(() => {
expect(screen.getByText("59s")).toBeInTheDocument();
}, 1000);
});
test("Value of clock after 1s", async () => {
render(<Clock />);
expect(screen.getByText("60s")).toBeInTheDocument();
jest.advanceTimersByTime(10000);
expect(await screen.findByText("59s")).toBeInTheDocument();
});
- This solution correctly test 1s warrant, however fails with 10s.
test("Value of clock after 1s", async () => {
render(<Clock />);
const headerElement = screen.getByRole("heading");
jest.advanceTimersByTime(1000);
await waitFor(() => expect(headerElement.innerHTML).toBe("59s"));
});
I have no clue what the problem is to be honest.
CodePudding user response:
Your useEffect hook needs a dependency array for the clock state
like so:
useEffect(() => {
const tick = setInterval(() => {
setClock(clock - 1);
}, 1000);
if (clock === 0) {
dispatch({ type: "breakDone" });
}
return function cleanUp() {
clearInterval(tick);
};
},[clock]);