[react-testing-library] svg 컴포넌트 테스트하기

pds·2023년 3월 10일
0

TIL

목록 보기
55/60

SVG 아이콘을 컴포넌트로 사용할 때 RTL에서 발생했던 문제를 해결해보았다.

문제상황

애플리케이션에서 SVG 아이콘들을 직접 public 경로에 두고 사용하는데 이들을 컴포넌트화 해서 사용하고 있었다.

... //next.config.js
  webpack(config) {
    config.module.rules.push({
      test: /\.svg$/,
      use: ['@svgr/webpack'],
    });

    return config;
  },

@svgr/webpack 라이브러리를 활용해서 컴포넌트로 import해서 사용하고 있다.


import Icon1 from '@/public/icons/icon1.svg'; 
import Icon2 from '@/public/icons/icon2.svg'; 

const Icons = {
	Icon1, Icon2
};


const Icon = ({ icon, color, size, className = '' }: IconProps) => {
  const SVGIcon = Icons[icon];
  return (
    <IconLayout color={color} size={size}>
      <SVGIcon className={className} viewBox="0 0 24 24" />
    </IconLayout>
  );
};

storybook 환경에서도 인식시켜주었고 실행환경에서도 잘 되는데 jest,react-testing-library로 컴포넌트 테스트를 할 때 문제가 생겼다.


string이 아닌 object가 식별되었다는데

jest환경에서 이 SVG컴포넌트를 인식을 못해서 발생하는 오류같다.

그래서 여기를 찾아보니 jest환경에서 svg컴포넌트를 사용할 때 추가적으로 환경설정을 해줘야했었다.


해결책

 svg와 연결할 mock 파일을 만들어주고

jest.config.js에 svg를 mock svg로 인식하게 설정을 해준다.


비슷하게 해결해보기

결국은 해당 라이브러리로 svg컴포넌트를 사용할 때 테스트환경에서는 따로 mocking을 해주어야 한다는 것이 결론이다.

모든 svg파일을 아이콘 컴포넌트로만 사용하고 있기 때문에 조금 더 쉬운 방법이 생각났다.


jest 환경에 global하게 mocking하기

jest.mock('./components/common/Icon', () => {
  const MockedIcon = ({ icon }) => <div>{icon}</div>;
  return MockedIcon;
});

어차피 components/common/Icon이라는 컴포넌트를 통해서만 svg 컴포넌트를 사용하는 상황이라 해당 컴포넌트 자체를 jest환경에서 전역으로 mocking해주었다.

그리고 해당 컴포넌트에서는 등록된 모든icon에 대한 이름 타입을 필수 props로 가지고 있어서

단순히 빈 div ReactComponent로 나오게 하기보다는 어떤 아이콘을 사용하는지 텍스트로 jest에서 찾을 수 있게 props도 넘겨주었다.


import Icon from '@/components/common/Icon';
import { render } from '@testing-library/react';

it('Icon 컴포넌트는 Icon text를 가지는 MockedIcon 컴포넌트를 렌더링한다.', () => {
  const { container } = render(<Icon icon="Ax" />);
  expect(container).toHaveTextContent('Ax');
});


이런식으로 아이콘을 활용한 버튼 컴포넌트에 대해 따로 svg를 실제로 로드하거나 하지 않고도 쉽게 찾아서 이벤트 테스트를 할 수 있어 좋은 것 같다!


References

profile
강해지고 싶은 주니어 프론트엔드 개발자

0개의 댓글