아래 부분은 커스텀 훅을 테스트
작성한 커스텀 훅을 테스트하려다 보니,
useLocation() may be used only in the context of a component.
이런 에러가 난다.
useLocation은 라우터의 컨텍스트 안에서만 사용할 수 있기 때문에 테스트 코드에서 실행할 수 없는 것이다.
그럼 useLocation을 어떻게 테스트할 수 있을지 방법을 찾아보자.
공식문서에서는 따로 해당 내용을 찾지 못해 스택오버플로우를 뒤져봤다.
스택 오버플로우
이런 방법도 시도해봤다.
import { render } from '@testing-library/react';
import React from 'react';
import { MemoryRouter } from 'react-router-dom';
import { Test } from './';
describe('68248240', () => {
it('should pass', () => {
render(
<MemoryRouter initialEntries={[{ pathname: '/', search: '?value=teresa_teng' }]}>
<Test />
</MemoryRouter>
);
});
});
이렇게 만들었지만...
다시 이런 에러가 뜬다. TypeError: (0 , _reactHooks.render) is not a function
describe('useQueryStringObject', () => {
it('test', () => {
render(
<MemoryRouter>
<useQueryStringObject />
</MemoryRouter>
);
테스트를 작성할 때를 염두에 두고 함수를 최대한 분리해서 가져가야 하나?
예를 들어서,
const [unAvailableDates, setUnavailableDates] = useState([]);
function checkFirstUnAvailableDates() {
for (let i = 0; i < unAvailableDates.length; i++) {
if (moment(unAvailableDates[i]).isAfter(startDate)) {
return unAvailableDates[i];
}
}
}
이러한 방식으로 mock함수로 순수로직만을 가져와 하나하나의 유닛을 작은 단위로 쪼개 테스트하는 방식으로 결국 해결했다.
여전히 남은 고민은, 그럼 실무에서는 이럴 때 어떻게 해결할까? 라는 것이었다.
이 질문에 대한 답은 방법을 찾다가 해결하지 못했는데, 테스트를 하기에 적절하지 않은 코드를 작성했을 수 있다는 생각이 들어 좋은 테스트 전략에 대해 더 공부해보고자 하는 마음이 생겼다.
그리고 실용적인 리액트 테스트 전략 이라는 글을 찾아 읽게 되었는데, 나름대로 정리해본 생각은 다음과 같다.
- 리액트에서 커스텀 훅과 리덕스 테스트는 필수적이다.
- 컴포넌트 단위의 테스트는 자칫 리액트 자체를 테스트하게 될 수 있다. 또한 스냅샷 테스트는 UI요소가 쉽게 자주 바뀔 수 있기 때문에 효율성 측면에서도 고민해볼 필요가 있다. Storybook을 사용해 문서화 및 컴포넌트 테스트를 진행하는 것도 좋은 방법이 될 수 있다.
그리고 앞으로는 테스트를 염두에 두고 useLocation과 같은 로직을 포함하지 않는 것이 어떨까 싶다. TDD를 하면 가능해질 것 같은데, 이번에는 테스트를 염두에 두지 않은 채로 개발부터 진행해서 이런 상황이 펼쳐진 것 같다.
다음부턴 이 부분을 염두에 두고 개발을 진행하도록 하자..!
- 실용적인 리액트 테스트 전략: https://velog.io/@sdong001/%EC%8B%A4%EC%9A%A9%EC%A0%81%EC%9D%B8-%EB%A6%AC%EC%95%A1%ED%8A%B8-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%A0%84%EB%9E%B5