특정 use hook을 모킹 하여 테스트 코드를 작성 중 다음과 같은 에러가 발생하였다.
ReferenceError: /Users/classting/github/aidt/apps/web/src/features/course/components/TextbookContentContainer/TextbookContentContainer.spec.tsx: The module factory of `jest.mock()` is not allowed to reference any out-of-scope variables.
const ToastFn = jest.fn();
jest.mock('@components/ui', () => ({
...jest.requireActual('@components/ui'),
useToast: () => ({ toast: ToastFn, dismiss: jest.fn() }), // 에러 코드 위치
}));
모킹하는 코드가 잘못된 줄 알고 여러 삽질을 했었는데, 에러 메시지에 상세한 해결방법이 나와있었다.
Note: This is a precaution to guard against uninitialized mock variables. If it is ensured that the mock is required lazily, variable names prefixed with mock(case insensitive) are permitted.
자세히 해석해보면, jest.mcok으로 선언한 코드는 호이스팅이 되기 때문에 외부 스코프에 있는 변수에 접근할 수 없다는 에러이다.
// mock 코드는 호이스팅 되어 최상단에 선언된 것 처럼 동작함
jest.mock('@components/ui', () => ({
...jest.requireActual('@components/ui'),
useToast: () => ({ toast: ToastFn, dismiss: jest.fn() }),
}));
// 호이스팅 후 변수 선언이 됨
const ToastFn = jest.fn();
해결 방법
variable names prefixed with mock(case insensitive) are permitted.
변수명 앞에 mock으로 시작하게 되면 해당 호이스팅을 막게되어 에러를 해결할 수 있다.
const mockToastFn = jest.fn(); // mock으로 시작하는 변수명으로 변경
jest.mock('@components/ui', () => ({
...jest.requireActual('@components/ui'),
useToast: () => ({ toast: mockToastFn, dismiss: jest.fn() }),
}));
이렇게 변수명 하나를 바꾸니 에러가 해결되었다!
알게 된 점
해당 트러블 슈팅을 통해 알게된 점은 내 코드가 무엇이 잘못되었는지 아는 것이다.
에러가 발생하면 무작정 발생한 코드를 다르게 수정하기보다는 에러 코드를 보며 "어떤 점"이 잘못되었는지 알고 해결하는 것이다.
그렇게 먼저 문제점이 알고 해결하면 어떠한 점이 문제였고, 어떻게 해결하고, 그런 것들을 분석하다 보면 코드의 동작과정까지 알게 되는 경우가 많다. 그러니 꼭! 문제가 생기면 에러 메시지를 보면서 어떤 것이 문제인지 알려고 하는 습관을 기르자.
Reference
'에러일지' 카테고리의 다른 글
Mathlive Virtual Keyboard 커스텀하기 & 특정 컴포넌트 module css에서 선언한 스타일이 글로벌로 적용되지 않는 이유, 해결방법 (0) | 2024.04.28 |
---|---|
Error: Invalid Hook Call Error, React 종속성 문제 (0) | 2024.01.02 |
Cross-Origin Resource Sharing (CORS) (0) | 2024.01.02 |