Jest Configuration 질문

문제 상황

RN with TS 로 작업을 하면서 많은 dependencies가 추가되었는데,
yarn test로 테스트를 진행하려고 보니, 외부 라이브러리 module을 import 하는데 계속 오류가 발생하고 있습니다.

// package.json
{
  "name": "",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "start": "react-native start",
    "test": "jest",
    "lint": "eslint . --ext .js,.jsx,.ts,.tsx"
  },
  "dependencies": {
    "@react-native-async-storage/async-storage": "react-native-async-storage/async-storage",
    "@react-native-community/art": "^1.2.0",
    "@react-native-community/cli": "^5.0.1-alpha.2",
    "@react-native-community/hooks": "^2.6.0",
    "@react-native-community/netinfo": "^6.0.0",
    "@react-navigation/bottom-tabs": "^6.0.2",
    "@react-navigation/native": "^6.0.2",
    "@react-navigation/stack": "^6.0.4",
    "@reduxjs/toolkit": "^1.5.1",
    "i18n-js": "^3.8.0",
    "jetifier": "^2.0.0",
    "moment": "^2.29.1",
    "react": "17.0.1",
    "react-native": "0.64.2",
    "react-native-android-location-enabler": "^1.2.2",
    "react-native-base64": "^0.2.1",
    "react-native-ble-plx": "^2.0.2",
    "react-native-dash": "^0.0.11",
    "react-native-device-info": "^8.1.3",
    "react-native-fs": "^2.18.0",
    "react-native-gesture-handler": "^1.10.3",
    "react-native-keyboard-aware-scroll-view": "^0.9.4",
    "react-native-linear-gradient": "^2.5.6",
    "react-native-localize": "^2.1.0",
    "react-native-orientation-locker": "^1.3.1",
    "react-native-picker": "^4.3.7",
    "react-native-progress": "^4.1.2",
    "react-native-responsive-fontsize": "^0.5.0",
    "react-native-safe-area-context": "^3.2.0",
    "react-native-screens": "^3.5.0",
    "react-native-signature-capture": "^0.4.12",
    "react-native-size-matters": "^0.4.0",
    "react-native-snackbar": "^2.4.0",
    "react-native-splash-screen": "^3.2.0",
    "react-redux": "^7.2.4",
    "styled-components": "^5.3.0",
    "ws": "^7.5.3"
  },
  "devDependencies": {
    "@babel/core": "^7.14.3",
    "@babel/runtime": "^7.14.0",
    "@react-native-community/eslint-config": "^2.0.0",
    "@types/i18n-js": "^3.8.1",
    "@types/jest": "^26.0.23",
    "@types/react": "^17",
    "@types/react-native": "^0.64.8",
    "@types/react-native-base64": "^0.1.0",
    "@types/react-native-signature-capture": "^0.4.2",
    "@types/react-test-renderer": "^17.0.1",
    "@types/styled-components": "^5.1.10",
    "@types/styled-components-react-native": "^5.1.1",
    "@typescript-eslint/eslint-plugin": "^3.10.1",
    "@typescript-eslint/parser": "^3.10.1",
    "@typescript-eslint/typescript-estree": "^3.10.1",
    "babel-jest": "^27.0.2",
    "babel-plugin-module-resolver": "^4.1.0",
    "eslint": "^7.27.0",
    "eslint-config-prettier": "^6.15.0",
    "eslint-plugin-prettier": "^3.1.2",
    "eslint-plugin-react": "^7.24.0",
    "eslint-plugin-react-hooks": "^4.2.0",
    "jest": "^27.0.3",
    "metro-react-native-babel-preset": "^0.66.0",
    "prettier": "^2.3.0",
    "react-test-renderer": "17.0.1",
    "typescript": "^4.3.4"
  },
  "resolutions": {
    "@types/react": "^17"
  },
  "jest": {
    "preset": "react-native",
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js",
      "jsx",
      "json",
      "node"
    ],
    "automock": true
  },
  "transformIgnorePatterns": [
    "node_modules/(?!(react-native|@react-native)/)"
  ]
}

// babael.config.js
module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: [
    ['babel-plugin-styled-components'],
    [
      'module-resolver',
      {
        root: ['./src'],
        extensions: [
          '.ios.js',
          '.android.js',
          '.ios.jsx',
          '.android.jsx',
          '.js',
          '.jsx',
          '.json',
          '.ios.ts',
          '.android.ts',
          '.ios.tsx',
          '.android.tsx',
          '.tsx',
          '.ts',
        ],
        alias: {
          'components/*': './src/components/*',
          'libraries/*': './src/libraries/*',
          'reducers/*': './src/reducers/*',
          'resources/*': './src/resources/*',
          'screens/*': './src/screens/*',
          'utils/*': './src/utils/*',
          'navigators/*': './src/navigators/*',
          'hooks/*': './src/hooks/*',
          'types/*': './src/types/*',
        },
      },
    ],
  ],
};


질문

jest 공식 문서 등을 참고해서 여러가지 jest config 값을 변경해보았지만, 하나가 해결되면, 다른 라이브러리에 대한 오류가 계속 뜨고 있네요…

혹시 가능한 오류 원인이 어떤 것들이 있을까요? dependencies와 무관하게 일단 test 실행이 되도록 할 수 있는 방법이 있을까요?

처음에 테스트를 구축하면 해야할게 생각보다 많아서 당황스럽죠 ㅜㅜ

일단 특정 라이브러리들을 mock up을 해주셔야 합니다.
특히 react native gesture handler 등의 특정 라이브러리들은 네이티브 코드와 연동되어 사용되는 경우가 있어 nodejs의 순수 테스트 환경에서는 동작이 불가능합니다.

https://reactnavigation.org/docs/testing/

위 링크를 보시면 gesture handler를 포함하여 여러 라이브러리들을 mocking 하는걸 볼 수 있는데 이것을 jestsetup 등의 파일에 넣거나 다른 방법들로 테스트 할때 제일 먼저 실행되도록 할 수 있습니다.

위 예제에서는 /jest/setup.js 에 목업코드를 넣었네요

{
  "preset": "react-native",
  "setupFiles": [
    "<rootDir>/jest/setup.js"
  ],
}
좋아요 1

말씀주신 내용대로 얼마전에 알아내서, mock으로 처리했더니 실행은 되네요 이제~
덕분에 또하나 배웠습니다. 감사합니다 :slight_smile:

좋아요 1