react testing library와 컴포넌트 테스트

정영찬·2024년 9월 3일

테스트 코드

목록 보기
6/9

testing Library

ui 컴포넌트 테스트를 도와주는 라이브러리이며 핵심 철학이 있다면 ui컴포넌트를 사용자가 사용하는 방식으로 테스트한다는 것이다.

이를 위해서 DOM 노드를 쿼리하고 사용자와 비슷한 방식으로 이벤트를 발생해서 테스트를 진행한다.

이전에 생성한 textfield 컴포넌트에서 추가적으로 테스트를 진행해보자.

텍스트를 입력할 때마다 onChange 핸들러 호출

  • focus 시 border 스타일 변경
  • focus 시 onFocus 핸들러 호출
it('텍스트를 입력하면 onChange prop으로 등록한 함수가 호출된다.', async () => {
  const spy = vi.fn(); // 스파이 함수 생성
  // 스파이 함수 : 다른 함수의 호출 여부, 호출 횟수, 호출 시 전달된 인자 등을 기록하는 함수
  const { user } = await render(<TextField onChange={spy} />);
  const textInput = screen.getByPlaceholderText('텍스트를 입력해 주세요.');

  await user.type(textInput, 'test');
  expect(spy).toHaveBeenCalledWith('test');
});

쿼리의 경우 기본 원칙에 따라 테스트는 사용자가 코드(컴포넌트, 페이지 등)와 상호 작용하는 방식과 최대한 유사해야 하며 이를 염두에 두고 다음 우선 순위를 따르는 것이 좋다.

모두가 액세스 가능한 쿼리(getByRole, getByLabelText,getByPlaceholderText,getByText,getByDisplayValue)
-> 시맨틱 쿼리 (getByaltText,getBtTitle) -> testIDs(getByTestId)

getByTestId를 사용하여 테스트를 제작한 경우 dom의 구조가 바뀔때 테스트가 깨져버릴 수 있다.

사용자가 직접 테스트 하는것처럼 구현하기 위해서 vi.fn()을 사용한다. 해당 함수를 사용하여 스파이 함수를 제작한다.

  • 스파이 함수 : 다른 함수의 호출 여부, 호출 횟수, 호출 시 전달된 인자 등을 기록하는 함수

Enter 키 입력 시 onEnter 핸들러 호출

it('엔터키를 입력하면 onEnter prop으로 등록한 함수갇 호출된다', async () => {
  const spy = vi.fn();
  const { user } = await render(<TextField onEnter={spy} />);
  const textInput = screen.getByPlaceholderText('텍스트를 입력해 주세요.');
  await user.type(textInput, 'test{Enter}');
});

사용자가 enter,alt,shift,space와 같은 키를 입력했는지를 확인하고 싶다면 typeApi의 경우 중괄호를 씌우고 원하는 키를 작성해주면 된다.

focus 시 border 스타일 변경

it('포커스가 활성화되면 border 스타일이 추가된다', async () => {
  const { user } = await render(<TextField />);
  const textInput = screen.getByPlaceholderText('텍스트를 입력해 주세요.');
  await user.click(textInput);

  expect(textInput).toHaveStyle('설정 되어야 하는 스타일 내용');
  // 
});

focus 시 onFocus 핸들러 호출

it('포커스가 활성화되면 onFocus prop으로 등록한 함수가 호출된다.', async () => {
  const spy = vi.fn();
  const { user } = await render(<TextField onFocus={spy} />);
  const textInput = screen.getByPlaceholderText('텍스트를 입력해 주세요.');
  await user.click(textInput);
  expect(spy).toHaveBeenCalled();
});
profile
개발자 꿈나무

0개의 댓글