1. 실습

1. React Testing Library

1. useDidMount

2. useDebounce

// src/hooks/useDebounce.ts
export default function useDebounce(value: string, delay = 300) {
  const [debouncedValue, setDebouncedValue] = useState(value);

  useEffect(() => {
    const handler = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);
    return () => {
      clearTimeout(handler);
    };
  }, [value, delay]);

  return debouncedValue;
}
  1. setTimeout, setInterval, clearTimeout, clearInterval을 가짜로 만들어준다.

    describe("useDebounce", () => {
      // ..
    	jest.useFakeTimers();
    }
    
  2. 즉시 실행했을 때

    describe("useDebounce", () => {
      // ..
    	it("동일한 값을 즉시 반환해야 한다", () => {
        const { result } = renderHook(() => useDebounce("test", 300));
        expect(result.current).toBe("test");
      });
    }
    

    renderHook을 이용하여 훅을 실행한다.

    이 때, debouncedValue는 result.current에 들어가게 된다.

  3. 값이 변경되지 않았을 때

    describe("useDebounce", () => {
      // ..
    	it("값이 변경되지 않았다면 지연 후에도 동일한 값을 반환해야 한다", () => {
        const { result } = renderHook(() => useDebounce("test", 300));
        act(() => {
          jest.advanceTimersByTime(300);
        });
        expect(result.current).toBe("test");
      });
    }
    

    jest.advanceTimersByTime();를 이용해서 300ms시간을 흘려 보냈다.

    하지만, 그 사이에 값 변동이 없었기 때문에 동일한 값을 return한다.

  4. 값을 변경했을 때

    describe("useDebounce", () => {
      // ..
    	it("지연 시간이 지나기 전까지는 디바운스된 값이 업데이트되지 않아야 한다", () => {
        const { result, rerender } = renderHook(
          ({ value }) => useDebounce(value, 300),
          {
            initialProps: { value: "initial" }
          }
        );
        rerender({ value: "updated" });
        act(() => {
          jest.advanceTimersByTime(250);
        });
        expect(result.current).toBe("initial");
        act(() => {
          jest.advanceTimersByTime(50);
        });
        expect(result.current).toBe("updated");
      });
    }
    

    renderHook을 실행하는데, 두 번째 인자의 initiaProps에 value로 initial을 넣는다. 그리고, value를 updated로 리렌더링을 수행한다.

    250ms가 지났을 때는 여전히 initial이지만, 50ms가 더 지났을 때는 updated로 값이 변경되어 있다.

2. cypress

1. 사용자가 input에 값을 입력 하면 url이 바뀌는 지 테스트한다