Home > Back-end >  Testing React component -> setInterval
Testing React component -> setInterval

Time:10-05

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:

  1. 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();
  });
  1. 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]);
  • Related