[Testing] Redux를 활용하는 컴포넌트를 테스트 할 때 주의할 점 (문제-해결 과정, 개선 결과)
요즘 모든 프로젝트에 test 파일을 작성하고 있습니다.
하지만 처음 적용하다 보니 이런저런 문제를 만나게 되는데,
그중 가장 인상깊었던 문제-해결 과정을 글로 작성해보려 합니다
문제: Navbar 컴포넌트가 Redux의 Provider로 감싸여 있지 않아서 오류가 발생
에러로그
에러 로그
renders Navbar and children could not find react-redux context value; please ensure the component is wrapped in a <Provider> 8 | 9 | const Navbar = () => { > 10 | const dispatchFn = useDispatch();
에러 메시지를 확인하여 Navbar 컴포넌트에서 react-redux의 Provider로 감싸여 있지 않다는 것을 알 수 있었습니다.
문제해결: 테스트할 컴포넌트를 Provider로 감싸줍니다
따라서 테스트하는 컴포넌트를 redux Provider로 감싸야하므로 아래와 같이 코드를 작성하였습니다
test("renders Navbar and children", () => {
render(
<Provider store={store}>
<Layout>
<div>Test children</div>
</Layout>
</Provider>
);
문제: 모든 테스트 파일에 Provider를 임포트 하고 감싸줘야하는 문제
위와 같이 코드를 수정하면 쉽게 문제가 해결되지만,
저는 모든 테스트 파일에 Provider와 store를 임포트하고 감싸줘야 한다는 점이 매우 불편하고 비효율적이라 느꼈고,
이를 설정 파일에서 한번 설정하고 그것을 활용해 보자 라는 방식을 고안했습니다
문제해결: render 함수 오버라이드
render 함수를 오버라이드하여 Provider 컴포넌트를 포함한 래퍼 함수를 생성할 수 있다는 것을 알게 되었습니다.
또한 jest.config.js 파일에서 setupFilesAfterEnv 속성을 사용하여 jest.setup.js 파일을 실행시킬 수 있으므로,
jest.setup.js 파일에서 render 함수를 오버라이드하여 Provider를 포함한 래퍼 함수를 생성하고, 이를 테스트 파일에서 사용하도록 설정했습니다.
// jest.setup.js
import { render as rtlRender } from "@testing-library/react";
import { Provider } from "react-redux";
import store from "./src/store/store.js";
const render = (ui, options) => {
const Wrapper = ({ children }) => <Provider store={store}>{children}</Provider>;
return rtlRender(ui, { wrapper: Wrapper, ...options });
};
export * from "@testing-library/react";
export { render };
이후 모든 테스트 파일에 Provider와 store를 임포트 하는 것이 아닌, 커스텀 render 함수만 임포트 하면 되는 방식으로 개선시켰습니다
문제 해결 후: 모든 오류가 해결되었고 테스트가 정상적으로 실행되고 원하는 결과를 얻을 수 있게 되었습니다.