- Published on
[React Testing] Jest와 svgr
- Authors

jangth
테스트 코드를 작성하던 중 svgr 컴포넌트를 사용하고 있는 컴포넌트에서 에러가 발생하였다.
console.error
Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.
해당 에러는 React가 컴포넌트를 렌더링할 때 예상치 못한 타입을 받았음을 말해주고 있다. svg 아이콘을 컴포넌트화 하여 사용할 수 있게 해주는 svgr을 사용중인데, svgr 컴포넌트를 svg태그로 변환할 수 없는 상황에서 발생한 것으로 보인다.
즉 RTL의 render함수는 리액트 컴포넌트를 node.js 객체인 jsDOM으로 변환해야 하는데 svgr 컴포넌트를 svg 태그로 변환할 수 없기 때문에 발생한 것으로 생각한다.
✅ 해결책
jest, RTL에서는 실제 아이콘이 렌더링되는지 UI를 직접적으로 확인하는 것이 아니기 때문에 svg 컴포넌트를 간단한 리액트 컴포넌트로 모킹하기만 하면된다.
- mocks/svg.js
import React from 'react';
// eslint-disable-next-line react/display-name
const SvgrMock = React.forwardRef((props, ref) => <span ref={ref} {...props} />);
export const ReactComponent = SvgrMock;
export default SvgrMock;
﹒왜 fowardRef 사용? svgr 라이브러리는 svg 아이콘을 리액트 컴포넌트처럼 사용하도록 설정해주는데, 이때 svg 컴포넌트가 ref를 props로 받을 수 있기 때문이다.
﹒export const ReactComponent = SvgrMock;와 export default SvgrMock; export와 export default를 모두 지원하기 위해서이다. 왜냐하면 프로젝트 내에서 svg 컴포넌트를 가져오는 방식이 다를 수 있는데, 테스트 코드에서는 모킹한 svg만 조회 또는 확인만 하면 되기 때문에 export, export default 등 내부적인 구현 방식에 의존하지 않도록 해야한다.
- jest config
//...
moduleNameMapper: {
'^.+\\.(svg)$': '<rootDir>/__mocks__/svg.js',
},
mocks 폴더에 svg컴포넌트를 default로 export한 후 jest config에서 해당 svg 목 파일을 설정해 두면 svgr 컴포넌트를 포함하는 코드를 테스트할 때 "svgr 컴포넌트를 -> span 태그" 로 대체되어 테스트를 진행하게 된다.
✔️ 참고 사이트
https://stackoverflow.com/questions/63511683/testing-mocking-reactcomponent-svg-imports-with-jest
https://github.com/gregberge/svgr/issues/83#issuecomment-1196022120
