Testing React Apps[Jest]

SnowCat·2023년 2월 28일
0

Jest

목록 보기
5/6
post-thumbnail

setup

npm install --save-dev react-test-renderer

create react app을 사용하지 않을시

npm install --save-dev jest babel-jest @babel/preset-env @babel/preset-react react-test-renderer

Snapshot Testing

  • 컴포넌트 형태를 미리 정해둔 스냅샷을 저장해 이를 비교하는 스냅샷 테스트를 진행할 수 있음
    // Link.js
import {useState} from 'react';

const STATUS = {
  HOVERED: 'hovered',
  NORMAL: 'normal',
};

export default function Link({page, children}) {
  const [status, setStatus] = useState(STATUS.NORMAL);

  const onMouseEnter = () => {
    setStatus(STATUS.HOVERED);
  };

  const onMouseLeave = () => {
    setStatus(STATUS.NORMAL);
  };

  return (
    <a
      className={status}
      href={page || '#'}
      onMouseEnter={onMouseEnter}
      onMouseLeave={onMouseLeave}
    >
      {children}
    </a>
  );
}

Link.test.js

import renderer from 'react-test-renderer';
import Link from '../Link';

it('changes the class when hovered', () => {
  const component = renderer.create(
    <Link page="http://www.facebook.com">Facebook</Link>,
  );
  let tree = component.toJSON();
  expect(tree).toMatchSnapshot();

  // 강제로 콜백 실행
  renderer.act(() => {
    tree.props.onMouseEnter();
  });
  // 새로운 스냅샷 저장
  tree = component.toJSON();
  expect(tree).toMatchSnapshot();

  renderer.act(() => {
    tree.props.onMouseLeave();
  });

  tree = component.toJSON();
  expect(tree).toMatchSnapshot();
});
  • 테스트를 처음 실행시 아래와 같은 스냅샷이 생성됨
    Link.test.js.snap
exports[`changes the class when hovered 1`] = `
<a
  className="normal"
  href="http://www.facebook.com"
  onMouseEnter={[Function]}
  onMouseLeave={[Function]}
>
  Facebook
</a>
`;

exports[`changes the class when hovered 2`] = `
<a
  className="hovered"
  href="http://www.facebook.com"
  onMouseEnter={[Function]}
  onMouseLeave={[Function]}
>
  Facebook
</a>
`;

exports[`changes the class when hovered 3`] = `
<a
  className="normal"
  href="http://www.facebook.com"
  onMouseEnter={[Function]}
  onMouseLeave={[Function]}
>
  Facebook
</a>
`;
  • 테스트를 다시 실행하면 처음 테스트 실행시의 스냅샷과 비교를 하게 됨
  • 스냅샷 테스트에 실패하면 의도하지 않은 변경을 수정하거나, jest -u 커맨드를통해 스냅샷을 덮어씌워야 함

DOM Testing

  • 렌더링되는 DOM을 테스트하고 싶으면 react-testing-library 사용

CheckboxWithLabel.js

import {useState} from 'react';

export default function CheckboxWithLabel({labelOn, labelOff}) {
  const [isChecked, setIsChecked] = useState(false);

  const onChange = () => {
    setIsChecked(!isChecked);
  };

  return (
    <label>
      <input type="checkbox" checked={isChecked} onChange={onChange} />
      {isChecked ? labelOn : labelOff}
    </label>
  );
}

CheckboxWithLabel.test.js

import {cleanup, fireEvent, render} from '@testing-library/react';
import CheckboxWithLabel from '../CheckboxWithLabel';

afterEach(cleanup);

it('CheckboxWithLabel changes the text after click', () => {
  const {queryByLabelText, getByLabelText} = render(
    <CheckboxWithLabel labelOn="On" labelOff="Off" />,
  );

  expect(queryByLabelText(/off/i)).toBeTruthy();

  fireEvent.click(getByLabelText(/off/i));

  expect(queryByLabelText(/on/i)).toBeTruthy();
});

출처:
https://jestjs.io/docs/tutorial-react

profile
냐아아아아아아아아앙

0개의 댓글