컴포넌트의 style 작성에는 여러가지 선택지가 있습니다.
그 중 저는 styled-components 를 가장 선호합니다.
이번 포스팅에서는 styled-components 를 사용한 컴포넌트를 테스트하기 위한 jest 환경을 설정해보겠습니다.
styled-components 는 <ThemeProvider />
하위에서 사용할 수 있습니다.
만약 추가 설정없이 jest 를 실행하게 되면, render()
호출에서 에러가 발생합니다.
import MyComponent from './MyComponent';
import {
render,
} from '@testing-library/react';
describe('MyComponent 테스트', () => {
it('DOM 에 렌더링 된다.', () => {
// render() 호출 시, Error 발생
render(
<div data-testid="my-component">
<MyComponent />
</div>
);
const $myComponent = screen.getByTestId('my-component');
expect($myComponent).toBeInTheDocument();
});
});
TypeError: Cannot read properties of undefined (reading 'MarkdownAnchor')
아래와 같이 render()
호출부에 <ThemeProvider />
를 함께 넘겨주면 테스트가 정상적으로 실행되는 것을 확인할 수 있습니다.
import MyComponent from './MyComponent';
import {
render,
} from '@testing-library/react';
describe('MyComponent 테스트', () => {
it('DOM 에 렌더링 된다.', () => {
// render() 성공
render(
<div data-testid="my-component">
<ThemeProvier theme={theme}>
<MyComponent />
</ThemeProvier>
</div>
);
const $myComponent = screen.getByTestId('my-component');
// 테스트 통과
expect($myComponent).toBeInTheDocument();
});
});
<ThemeProvider />
제공하기테스트 코드를 작성할 때, 각 테스트 케이스별로 중복되는 코드들이 생기게 됩니다.
이러한 부분들을 공통 함수로 묶어내거나 추상화하지 않는 이유는, 테스트 코드를 읽어나가는 것으로 어떤 테스트를 수행하는지 파악할 수 있는 것이 더 테스트 코드의 가치를 높이기 때문입니다.
하지만 <ThemeProvider />
를 감싸는 코드는 styled-components 설정을 테스트하는 것이 아닌 이상, 특정 컴포넌트를 테스트하는데 의미를 두기 어렵습니다.
그러므로 이 부분은 별도의 util 함수 또는 custom hook 으로 분리하여 사용해도 무방해 보입니다.
저는 @testing-library 에서 제공하는 render()
함수 처럼 util 함수
로 만드는 것이 좀 더 일관되는 패턴으로 생각하여 아래와 같이 작성해 보았습니다.
// react
import {
ReactElement,
} from 'react';
// jest
import {
render,
} from '@testing-library/react';
// styled-components
import {
ThemeProvider,
} from 'styled-components';
import theme from '@/styles/theme';
const renderTestComponent = (element: ReactElement) => {
const { rerender } = render(
<ThemeProvider theme={theme('light')}>
{element}
</ThemeProvider>
);
return {
rerender,
};
};
export default renderTestComponent;
이를 테스트 코드에 적용하면 다음과 같습니다.
import MyComponent from './MyComponent';
// import {
// render,
// } from '@testing-library/react';
import renderTestComponent from '@/utils/testing-library/renderTestComponent';
describe('MyComponent 테스트', () => {
it('DOM 에 렌더링 된다.', () => {
// render() 성공
renderTestComponent(
<div data-testid="my-component">
<MyComponent />
</div>
);
const $myComponent = screen.getByTestId('my-component');
// 테스트 통과
expect($myComponent).toBeInTheDocument();
});
});
유닛 테스트를 하나씩 추가하며, coverage 가 높아져 가는 것이 하나의 재미요소가 되었습니다.
renderTestComponent()
처럼 테스트 환경을 위한 기능을 만드는 과정은 성취감과 연결되었습니다.
이 블로그 프로젝트는 개발 초기 시점인 만큼, 모든 컴포넌트를 테스트할 수 있도록 목표를 잡아야겠습니다!