타이머를 제어하기 위해 vi.useFakeTimers1와 vi.advanceTimersByTime2을 사용하기.

describe('Countdown 컴포넌트', () => {
  beforeEach(() => {
    vi.useFakeTimers()
  })

  afterEach(() => {
    vi.useRealTimers()
  })

  test('타이머가 동작하며 시간을 업데이트한다.', () => {
    const endTime = new Date(Date.now() + 60000).toISOString()
    const renderChild = vi.fn(({ targetRef }) => (
      <div ref={targetRef} data-testid="countdown" />
    ))

    render(<Countdown end_at={endTime}>{renderChild}</Countdown>)

    expect(screen.getByTestId('countdown')).toBeEmptyDOMElement()

    act(() => {
      vi.advanceTimersByTime(10000)
    })

    expect(screen.getByTestId('countdown')).toHaveTextContent('00:00:50')

    act(() => {
      vi.advanceTimersByTime(50000)
    })

    expect(screen.getByTestId('countdown')).toHaveTextContent('00:00:00')
  })
})

Footnotes

  1. vi.useFakeTimers | Vitest: “To enable mocking timers, you need to call this method. It will wrap all further calls to timers (such as setTimeout, setInterval, clearTimeout, clearInterval, setImmediate, clearImmediate, and Date) until vi.useRealTimers() is called.” ↩

  2. vi.advanceTimersByTime | Vitest: “This method will invoke every initiated timer until the specified number of milliseconds is passed or the queue is empty - whatever comes first.” ↩

`#327`