HOW-TO GUIDES

next.js에서 타입스크립트 리액트 테스트 환경 셋업하기

encredible 2021. 8. 7. 22:18

react typescript jest

npx create-next-app my-test-app --ts

위의 명령문을 이용하여 타입스크립트로 next.js 프로젝트를 만들게 되면 프로젝트 내에 jest와 react testing library를 사용할 환경이 마련되어 있지 않습니다. (create-react-app을 사용하는 경우 다 설정되어 있지만..) 그래서 따로 설정을 해주어야 하는데 언어를 TypeScript로 하셨다면 조금 더 복잡한 과정을 거치게 됩니다. 필수적인 내용만으로 최대한 간결하게 정리하였습니다. jest의 다양한 기능을 활용하시고자 한다면 jest 공식 홈페이지를 참조하시길 바랍니다. 아, 타입스크립트를 언어로 선택했으나, root위치에 *.config.ts 파일로 놓으면 컴파일 옵션을 변경해주어야 하여 부득이하게 *.config.js로 하였습니다.

1. 라이브러리 설치

npm i -D identity-obj-proxy jest ts-jest @types/jest @testing-library/jest-dom @testing-library/react @testing-library/user-event

위의 명령어로 필요한 라이브러리를 설치해주도록 합니다. 참고로 i는 install의 축약형이고 -D는 --save-dev의 축약형입니다.

2. package.json

"scripts": {
    "test": "jest --detectOpenHandles --forceExit --coverage"
},

package.json파일의 scripts에 test를 추가해줍니다. jest를 호출하도록 하면 됩니다. 이렇게 하면 test script는 npm run test가 아니라 npm test로 test를 실행할 수 있습니다.

  1. detectOpenHandles는 열려있는 리소스를 모두 닫아줍니다.
  2. forceExit로 테스트가 끝나면 강제 종료를 해줍니다.
  3. coverage 옵션을 사용하면 만든 테스트가 코드를 얼만큼 테스트하는지 보여줍니다.

1, 2를 안 하면 mount, unmount에 대한 에러 메시지가 나오니 둘다 하시면 좋습니다.

3. jest.config.js

const config = {
    moduleNameMapper: {
        "\\.module\\.(css|scss)$": "identity-obj-proxy",
        "\\.(css|styl|less|sass|scss)$": require.resolve('./__mocks__/styleMock.js'),
        "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": require.resolve("./__mocks__/fileMock.js")
    },
    transform: {
        "^.+\\.(ts|tsx)$": "ts-jest"
    },
    testEnvironment: "jsdom",
    globals: {
        "ts-jest": {
            "tsconfig": "tsconfig.jest.json"
        }
    }
};

module.exports = config;

jest.config.js 파일입니다. package.json과 같은 위치에 넣어 주시면 됩니다.

  1. moduleNameMapper:각 확장자를 맵핑 시켜주는 도구입니다.
    1. CSS module을 사용하는 경우 identity-obj-proxy를 사용하지 않으면 빌드 자체가 되지 않습니다.
    2. CSS module 외의 것들은 styleMock.js를 사용하여 대치시켜줍니다.
    3. file을 fileMock.js를 사용하여 대치시켜줍니다.
  2. transform: 타입스크립트 파일들을 ts-jest를 이용하여 변경시켜줍니다.
  3. testEnvironment: jsdom 환경에서 테스트를 하도록 해줍니다. node로 되어 있으면 test 실행이 되지 않습니다.
  4. globals 설정으로 transform에 사용하는 ts-jest가 동작하도록 해줍니다.

3.1. styleMock.js

module.exports = {};

jest.config.js에서 설정한 위치인 root 위치에 해당 이름으로 폴더를 만들어 이 파일을 넣어주시면 됩니다.

3.2. fileMock.js

module.exports = 'test-file-stub';

위와 같습니다.

3.3. tsconfig.jest.json

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "jsx": "react"
  }
}

4. 기타 문제

4.1. error TS2686: 'React' refers to a UMD global, but the current file is a module. Consider adding an import instead.

Test를 하려는 대상이 React를 import 하지 않은 경우이다. import React from 'react'를 해당 파일에 넣어주기만 하면 된다.

4.2. Error: Uncaught [TypeError: window.matchMedia is not a function]

이와 같은 에러가 나왔을 때는 jest의 공식 해결법을 참조하면 된다. JSDOM에 구현이 되지 않은 함수라 mock처리를 해줘야 하는데 해결법을 참조하면 쉽게 할 수 있다.

5. 참고자료

jest configuration 파일 생성 - https://jestjs.io/docs/configuration

jest configuration 파일 내용 - https://jestjs.io/docs/webpack

jest configuration 내용 참고 - https://velog.io/@taeung/COINSS-Next.js%EC%99%80-TypeScript-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0