Jest: [๋ฒ„๊ทธ] ๋ณ„๋„์˜ ๋””๋ ‰ํ† ๋ฆฌ์—์„œ ๋ฐœ๊ฒฌ ๋œ ์ค‘๋ณต ์ˆ˜๋™ ๋ชจ์˜

์— ๋งŒ๋“  2016๋…„ 11์›” 09์ผ  ยท  66์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: facebook/jest

๊ธฐ๋Šฅ ์„ ์š”์ฒญํ•˜๊ฑฐ๋‚˜ ๋ฒ„๊ทธ๋ฅผ๋ณด๊ณ  ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๊ณค์ถฉ

ํ˜„์žฌ ํ–‰๋™์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

์ฃผ์–ด์ง„ ํŒŒ์ผ ํŠธ๋ฆฌ :

src/app/modules
โ”œโ”€โ”€ module1
โ”‚ย ย  โ”œโ”€โ”€ index.js
โ”‚ย ย  โ”œโ”€โ”€ __tests__/
โ”œโ”€โ”€ module2
โ”‚ย ย  โ”œโ”€โ”€ index.js
โ”‚ย ย  โ”œโ”€โ”€ __tests__/

modules ๋””๋ ‰ํ† ๋ฆฌ ์™ธ๋ถ€์˜ ๋ชจ๋“ˆ์„ ๋””๋ ‰ํ† ๋ฆฌ ์ด๋ฆ„์œผ๋กœ ๊ฐ€์ ธ ์™€์„œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

import Module1 from '../modules/module1';
import Module2 from '../modules/module2';

module1 ๋ฐ module2 ๋ฅผ ์กฐ๋กฑ ํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜, ๋‚˜๋Š” ์ž‘์„ฑํ•˜๋Š” ๊ฒฝ์šฐ src/app/modules/module1/__mocks__/index.js ๋ฐ src/app/modules/module2/__mocks__/index.js , ๋‚˜๋Š” ์ฃผ์–ด์ง„์žˆ์–ด duplicate manual mock found ์—์„œ ์˜ค๋ฅ˜๋ฅผ jest-haste-map .

๊ทธ๋Ÿฌ๋‚˜ src/app/modules/__mocks__/{module1.js,module2.js} ๋ฅผ ๋งŒ๋“ค๋ ค๊ณ ํ•˜๋ฉด ๋ชจ์˜ ํŒŒ์ผ์ด ์‚ฌ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ๋™์ž‘์ด ๋ฒ„๊ทธ ์ธ ๊ฒฝ์šฐ ์žฌํ˜„ ๋‹จ๊ณ„๋ฅผ ์ œ๊ณตํ•˜๊ณ  ๊ฐ€๋Šฅํ•˜๋ฉด npm install ๋ฐ npm test ํ•  ์ˆ˜์žˆ๋Š” GitHub์˜ ์ตœ์†Œ ์ €์žฅ์†Œ๋ฅผ ์ œ๊ณตํ•˜์„ธ์š”.

์œ„์˜ ๋™์ž‘์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

์˜ˆ์ƒ๋˜๋Š” ๋™์ž‘์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

์ฒซ ๋ฒˆ์งธ ๊ฒฝ์šฐ๋Š” ๋‹ค๋ฅธ ๊ฒฝ๋กœ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๋‘ ๋ฒˆ์งธ ๊ฒฝ์šฐ๋Š” ๋ชจ๋“ˆ์˜ ๊ฒฝ๋กœ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ์ ์„ ๊ฐ์•ˆํ•  ๋•Œ ๋‘ ๋ฐฉ๋ฒ• ๋ชจ๋‘ ์ž‘๋™ ํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค.

--debug Jest๋ฅผ ๋‹ค์‹œ ์‹คํ–‰ํ•˜๊ณ  ์ธ์‡„๋˜๋Š” ์ „์ฒด ๊ตฌ์„ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๋…ธ๋“œ v6.2.0
npm v3.8.9
OS X 10.11.6

> NODE_ENV=test jest --env jsdom "--debug" "src/app/redux/modules/devices"

jest version = 17.0.0
test framework = jasmine2
config = {
  "moduleFileExtensions": [
    "js",
    "json"
  ],
  "moduleDirectories": [
    "node_modules"
  ],
  "moduleNameMapper": [
    [
      "^.+\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$",
      "/Users/paul/dev/tools/jest/mock-assets.js"
    ],
    [
      "^.+\\.css$",
      "identity-obj-proxy"
    ]
  ],
  "name": "dev",
  "setupTestFrameworkScriptFile": "/Users/paul/dev/tools/jest/setup-framework.js",
  "testPathDirs": [
    "/Users/paul/dev/src"
  ],
  "testRegex": "/__tests__/.*\\.test\\.js$",
  "timers": "fake",
  "rootDir": "/Users/paul/dev",
  "setupFiles": [],
  "testRunner": "/Users/paul/dev/node_modules/jest-jasmine2/build/index.js",
  "testEnvironment": "/Users/paul/dev/node_modules/jest-environment-jsdom/build/index.js",
  "transform": [
    [
      "^.+\\.jsx?$",
      "/Users/paul/dev/node_modules/babel-jest/build/index.js"
    ]
  ],
  "usesBabelJest": true,
  "automock": false,
  "bail": false,
  "browser": false,
  "cacheDirectory": "/var/folders/dm/vt920lmd6tzdq_709zkykwx40000gn/T/jest",
  "coveragePathIgnorePatterns": [
    "/node_modules/"
  ],
  "coverageReporters": [
    "json",
    "text",
    "lcov",
    "clover"
  ],
  "expand": false,
  "globals": {},
  "haste": {
    "providesModuleNodeModules": []
  },
  "mocksPattern": "__mocks__",
  "modulePathIgnorePatterns": [],
  "noStackTrace": false,
  "notify": false,
  "preset": null,
  "resetMocks": false,
  "resetModules": false,
  "snapshotSerializers": [],
  "testPathIgnorePatterns": [
    "/node_modules/"
  ],
  "testURL": "about:blank",
  "transformIgnorePatterns": [
    "/node_modules/"
  ],
  "useStderr": false,
  "verbose": null,
  "watch": false,
  "cache": true,
  "watchman": true,
  "testcheckOptions": {
    "times": 100,
    "maxSize": 200
  }
}
jest-haste-map: duplicate manual mock found:
  Module name: index
  Duplicate Mock path: /Users/paul/dev/src/app/modules/push-notification-manager/__mocks__/index.js
This warning is caused by two manual mock files with the same file name.
Jest will use the mock file found in:
/Users/paul/dev/src/app/modules/push-notification-manager/__mocks__/index.js
 Please delete one of the following two files:
 /Users/paul/dev/src/app/modules/image-file/__mocks__/index.js
/Users/paul/dev/src/app/modules/push-notification-manager/__mocks__/index.js


No tests found
  1 file checked.
  testPathDirs: /Users/paul/dev/src - 1 match
  testRegex: /__tests__/.*\.test\.js$ - 0 matches
  testPathIgnorePatterns: /node_modules/ - 1 match
Enhancement Confirmed Help Wanted

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์ด๊ฒƒ์€ ๋‚˜๋ฅผ ์œ„ํ•ด ์ผํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. jest.config.js์—์„œ :

module.exports = {
  // ...
  modulePathIgnorePatterns: ["<rootDir>/.*/__mocks__"]
};

์ž‘์€ ํ”„๋กœ์ ํŠธ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—์ด ๋ณ€๊ฒฝ์˜ ๋ฒ”์œ„ ๋‚˜ ์˜ํ–ฅ์„ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  66 ๋Œ“๊ธ€

+1

์ œ ๊ฒฝ์šฐ์—๋Š” cacheDirectory / var / folders / dm / vt920lmd6tzdq_709zkykwx40000gn / T / jest๋ฅผ ์ง€์šฐ๊ณ  npm ์ข…์†์„ฑ์„ ๋‹ค์‹œ ์„ค์น˜ํ•˜๋ฉด ์ด๋Ÿฌํ•œ ๋ฉ”์‹œ์ง€๊ฐ€ ์‚ฌ๋ผ์กŒ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ์€ ๋ฌธ์ œ๊ฐ€๋˜๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

https://github.com/facebook/jest/blob/cd8976ec50dbed79cfe07f275052cdd80d466e73/packages/jest-haste-map/src/index.js#L98

๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๊ฒƒ์„ ํ™•์ธํ•˜๋Š” ํ…Œ์ŠคํŠธ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋™์ž‘์ด ๋ช…์‹œ ์ ์œผ๋กœ ์›ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

https://github.com/facebook/jest/blob/8de90b320c87a0a36d68f6bd8177620a985df269/packages/jest-haste-map/src/__tests__/__snapshots__/index-test.js.snap#L15

์ถ”๊ฐ€ ๋œ ํ•ญ๋ชฉ :

https://github.com/facebook/jest/commit/cfade282fbbe2737b6dd2cee1cf3da3ee8624512

์ „์ฒด ๊ฒฝ๋กœ๊ฐ€ ์•„๋‹Œ basename ํ‚ค๋กœ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๊ฐ€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

/ cc @flarnie

์ฆ‰, ์ˆ˜๋™ ๋ชจ์˜๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋ชจ๋“ˆ์— ๋Œ€ํ•œ basename ๋Š” ํ”„๋กœ์ ํŠธ์—์„œ ์ „์—ญ ์ ์œผ๋กœ ๊ณ ์œ ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ๋‚ด ์‚ฌ์šฉ ์‚ฌ๋ก€์˜ ๊ฒฝ์šฐ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ž‘์—…์„ ํ•  ์ˆ˜ ์—†์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

import { MyWhatever } from 'models/MyWhatever/schema';
import { MyOtherWhatever } from 'models/MyOtherWhatever/schema';

๋™์‹œ์— ์ˆ˜๋™ ๋ชจ์˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. Jest๋Š” ํ˜„์žฌ ๋‘˜ ๋‹ค schema ๋ฅผ ์กฐ๋กฑํ•˜๊ณ  ๋ถˆํ‰ํ•˜๋Š” ๊ฒƒ์œผ๋กœ๋ณด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ์‚ฌ์†Œํ•œ ๊ฒƒ (s / schema / MyWhateverSchema /)์ด์ง€๋งŒ ํ…Œ์ŠคํŠธ๊ฐ€ ์•„๋‹Œ ์ฝ”๋“œ์˜ ์ด๋ฆ„์„ ๋ฐ”๊พธ๊ณ  ์žฌ๊ตฌ์„ฑํ•˜์—ฌ ๋†๋‹ด์„ ์ฆ๊ฒ๊ฒŒํ•˜๋Š” ๋ฒ„๊ทธ์ฒ˜๋Ÿผ ๋Š๊ปด์ง‘๋‹ˆ๋‹ค .๐Ÿž.

์˜ˆ, ์ด๊ฒƒ์€ ์ •๋ง ์งœ์ฆ๋‚ฉ๋‹ˆ๋‹ค. ์ˆ˜๋™ ์กฐ๋กฑ ์‹œ์Šคํ…œ์€ ์ •๋ง ์ข‹์ง€ ์•Š์œผ๋ฉฐ ์ƒํ™ฉ์„ ๊ฐœ์„  ํ•  ์ˆ˜์žˆ๋Š” PR์„ ๋ฐ›์•„ ๋“ค์—ฌ์„œ ๊ธฐ์ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ๋ชจ๋“  FB๋ฅผ ๊นจ์ง€ ์•Š๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.

๋ฉ‹์žˆ๋Š”. ๋‚ด์ผ ํŒจ์น˜๋ฅผ ์š”๋ฆฌ ํ•  ์‹œ๊ฐ„์ด ์žˆ์„์ง€ ๋ชจ๋ฅด์ง€๋งŒ ์•ฝ์†์€ ์—†์ง€๋งŒ ๐Ÿ˜…

@cpojer ์ด ๋™์ž‘์— ๋Œ€ํ•œ ํŠน๋ณ„ํ•œ ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

fb๊ฐ€ ๋ชจ๋“ˆ์— ๊ณ ์œ  ํ•œ ํŒŒ์ผ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ์‚ฌ์‹ค๊ณผ ๊ด€๋ จ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๊ฐ™์€ ์ด๋ฆ„์„ ๊ฐ€์ง„ ๋‘ ๊ฐœ์˜ ๋ชจ์˜๋ฅผ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์–ด๋–ป๊ฒŒ ๋ง์ด๋˜๋Š”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

์˜ˆ, mock๋„ "๊ธ€๋กœ๋ฒŒ"์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ถˆํ–‰ํžˆ๋„ ์šฐ๋ฆฌ๊ฐ€ ํ•จ๊ป˜ ์‚ด์•„์•ผํ•˜๋Š” ๋”์ฐํ•œ ๋””์ž์ธ์ž…๋‹ˆ๋‹ค. FB์—๋Š” ์ž˜๋ชป๋œ ์œ„์น˜์— 4000 ๊ฐœ ์ด์ƒ์˜ ๋ชจ์˜ ํŒŒ์ผ์ด ์žˆ์Šต๋‹ˆ๋‹ค (๊ทธ๋ฆฌ๊ณ  ์ข…์ข… ์ ์ ˆํ•œ ์œ„์น˜๋„ ์—†์Šต๋‹ˆ๋‹ค). ๋‚ด๋…„ ์ดˆ๋ฐ˜์—์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์œผ๋ฏ€๋กœ Jest์—์„œ ๊ฐœ์„  ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜คํ”ˆ ์†Œ์Šค ์šฉ Jest์˜ ๋™์ž‘์„ ๊ฐœ์„ ํ•˜๋Š” PR์„ ์ง€์›ํ•˜๊ฒŒ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ FB์—์„œ Jest์˜ ์ด์ „ ๋™์ž‘์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ๊ธฐ์ฉ๋‹ˆ๋‹ค.

@cpojer ๊นƒ๋ฐœ์€ ์–ด๋•Œ? ํ”Œ๋ž˜๊ทธ๋กœ ์ด๊ฒƒ์„ ํ™œ์„ฑํ™” / ๋น„ํ™œ์„ฑํ™”ํ•˜๋Š” ํ™๋ณด๋ฅผ ์ˆ˜๋ฝ ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

์˜ˆ, ๊ตฌ์„ฑ ์˜ต์…˜์ด์–ด์•ผํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ €๋Š” ๊ฒฝ๊ณ ์— ๋Œ€ํ•ด์„œ๋งŒ ๋งํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ผ๋ฐ˜์ ์ธ ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด์„œ๋„ ์ด์•ผ๊ธฐํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

@cpojer ์˜ค๋ฅธ์ชฝ-๋†๋‹ด์˜ ์–ด๋Š ๋ถ€๋ถ„์ด์ด ๋ถ€๋ถ„์„ ๋งŒ์ง€๋‚˜์š”?

ํ•ด๊ฒฐ ์ฝ”๋“œ๋Š” jest-runtime : https://github.com/facebook/jest/blob/master/packages/jest-runtime/src/index.js ์—์„œ ํ˜ธ์ถœ๋˜๋ฉฐ jest-resolve ๋ฐ jest-resolve-dependencies ์–ด๋”˜๊ฐ€์— ์žˆ์Šต๋‹ˆ๋‹ค. .

@cpojer ํฌ์ธํ„ฐ ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค : +1 :

@cpojer ์ด ๋™์ž‘์„ ์ „ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด JEST_USE_BASENAME_FOR_CACHING ์™€ ๊ฐ™์€ ์ „์—ญ ์žฌ์ •์˜๋Š” ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

์ ์–ด๋„ ์šฐ๋ฆฌ๋Š” ๊ณ ์œ ํ•˜์ง€ ์•Š์€ ํŒŒ์ผ ์ด๋ฆ„์„ ์ฆ๊ธธ ์ˆ˜ ์žˆ์œผ๋ฉฐ FB์—์„œ ์–ด๋–ค ๊ฒƒ๋„ ๊นจ์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋ฌผ๋ก  ์ผ์‹œ์ ์ธ ํ•ด๊ฒฐ์ฑ…์ž…๋‹ˆ๋‹ค.

๋‚ด ๋ง์€, ์ด๊ฒƒ์€ /etc/profile ๋˜๋Š” ~/.bashrc

export JEST_USE_BASENAME_FOR_CACHING="true"

(๋˜๋Š” env๊ฐ€์žˆ๋Š” ์ผ๋ถ€ ํŒŒ์ผ)
๊ทธ๋ฆฌ๊ณ 

$ jest

๋˜๋Š” ์ด๊ฒƒ์€ env ํŒŒ์ผ ์ˆ˜์ •์—†์ด :

$ JEST_USE_BASENAME_FOR_CACHING="true" jest

์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜์„ธ์š”? ์ผ์ข…์˜ ํ•ดํ‚น์ž…๋‹ˆ๊นŒ, ์•„๋‹ˆ๋ฉด ๊ดœ์ฐฎ์Šต๋‹ˆ๊นŒ? :๋ˆˆ์ง“:

๋‘ ๊ฐ€์ง€ ๋ฒ„์ „์˜ jest ( ^15.0.0 ๋ฐ ^17.0.0 )๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ repo ๋ฅผ ์‚ฌ์šฉํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค. ํ›„์ž๋Š” ๊ฒฝ๊ณ ๋ฅผ ํ‘œ์‹œํ•˜์ง€๋งŒ ํ…Œ์ŠคํŠธ๋Š” ์˜ˆ์ƒ๋Œ€๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

@ColCh ์—ฌ๊ธฐ์„œ ๋ฌธ์ œ๊ฐ€ ์บ์‹œ์— ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ๋” ์ ํ•ฉํ•œ ์ด๋ฆ„์€ JEST_USE_BASENAME_FOR_MOCKING ์žˆ์Šต๋‹ˆ๋‹ค.

FB ์ฝ”๋“œ์— ์ด๋ฆ„์˜ ๊ณ ์œ ์„ฑ์— ๋Œ€ํ•œ ์ œํ•œ์ด์žˆ๋Š” ๊ฒฝ์šฐ @cpojer , ์ „์ฒด ๊ฒฝ๋กœ๋ฅผ ๋ชจ์˜ ๋งต์˜ ํ‚ค๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ๋งž์Šต๋‹ˆ๊นŒ, ์•„๋‹ˆ๋ฉด ๋ณด์ด์ง€ ์•Š๋Š” ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๋‚ด๊ฐ€ ๋ณด๋Š” ๋‘ ๊ฐ€์ง€ ์†”๋ฃจ์…˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ๊ธฐ๋ณธ ์ด๋ฆ„ ๋˜๋Š” ์ „์ฒด ๊ฒฝ๋กœ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์˜ต์…˜์„ ์ˆ˜์šฉํ•˜๋„๋ก getMockName ์ˆ˜์ •
  • ๊ทธ ๊ธฐ๋Šฅ์„ ๋ชจ๋‘ ์ œ๊ฑฐ

@cpojer ๋‹ต๋ณ€์„ ๋ณด๋Š” ๊ฒƒ์ด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” ์—ฌ๋Ÿฌ๋ถ„, ์ง€์—ฐ๋˜์–ด ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” ์ง€๊ธˆ ๋งŽ์€ ์ž๋ฃŒ๋ฅผ ๋ฐฑ์—…ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ์‹œ์Šคํ…œ์„ ๊ฐœ์„ ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ Jest์˜ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ๋ฌด์—‡์ด๋“ ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•ด๋„ ๊ดœ์ฐฎ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ˆ˜๋™ ์กฐ๋กฑ์€ ์ •๋ง ์—‰๋ง์ด๊ณ  ์ž˜ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ํ•˜๊ณ  ์‹ถ์€ ํ•œ ๊ฐ€์ง€๋Š” "haste_modules": ['path/a', 'path/b']" ์™€ ๊ฐ™์€ ๊ตฌ์„ฑ ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ "haste modules"(๋‚ด๋ถ€ FB ๋ชจ๋“ˆ ์‹œ์Šคํ…œ)์˜ ๋ฒ”์œ„๋ฅผ ์ œํ•œ ํ•œ ๋‹ค์Œ์ด ์ด์ƒํ•œ ์กฐ๋กฑ์„ ํฌํ•จํ•˜์—ฌ ํ•ด๋‹น ํด๋”์—์žˆ๋Š” haste ๋ชจ๋“ˆ ๋งŒ ์‚ดํŽด ๋ณด๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ–‰๋™. ๋ˆ„๊ตฌ๋“ ์ง€์ด ๋ณ€ํ™”๋ฅผ ๋งŒ๋“ค๊ณ  ์‹ถ๋‹ค๋ฉด ๊ทธ๊ฒƒ์€ ๋†€๋ž์Šต๋‹ˆ๋‹ค.

์•Œ์•„ ๋‚ด์•ผ ํ•  ํ•œ ๊ฐ€์ง€๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. __mocks__/a.js ๊ฐ€ a.js ๋งคํ•‘๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ชจ๋“  ์ˆ˜๋™ ๋ชจ์˜๊ฐ€ ๋กœ์ปฌ์ด๋ฉด node_module ๋ชจ์˜๋กœ ๋ฌด์—‡์„ํ• ๊นŒ์š”? ์ด๋ฅผ ์œ„ํ•ด ๋ช‡ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ƒˆ๋กœ์šด __node_modules_mocks__ ํด๋”๋ฅผ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค.
  • rootDir (ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ)์—์„œ ํ‘œ์‹œ๋˜๋Š” ์ตœ์ƒ์œ„ __mocks__ ํด๋”๋Š” ์ „์—ญ ํด๋” ์—ญํ• ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์š”์•ฝํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • Jest์—์„œ ์ˆ˜๋™ ๋ชจ์˜๋ฅผ ๊ณ ์น˜์ž!
  • haste ๋ชจ๋“ˆ์„ ๋„ค์ž„ ์ŠคํŽ˜์ด์Šคํ•˜๊ณ  ํŠน์ • ํด๋” / ์ •๊ทœ์‹์œผ๋กœ ์ œํ•œํ•ฉ์‹œ๋‹ค.
  • ์„œ๋‘˜๋Ÿฌ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ํŠน์ • ํด๋”๋ฅผ ํ™”์ดํŠธ๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€ํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ์—๋„ ํ˜„์žฌ์˜ ์กฐ๋กฑ ๋™์ž‘์ด FB์—์„œ ์—ฌ์ „ํžˆ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค (์ง€๊ธˆ์€ ["<rootDir>"] ์ฒ˜๋Ÿผ ๋ณด์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค).
  • ์—ฌ์ „ํžˆ ๋…ธ๋“œ ๋ชจ๋“ˆ์„ ๋ชจ์˜ ํ•  ์ˆ˜์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„ ๋‚ด์‹ญ์‹œ์˜ค.

์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•ด?

์ˆœ์„œ๋Œ€๋กœ :

  • Jest์—์„œ ์ˆ˜๋™ ๋ชจ์˜๋ฅผ ๊ณ ์น˜์ž!

๋งŒ์„ธ : ๋ฏธ์†Œ :: ๋”ฐ๋‹ค :

  • haste ๋ชจ๋“ˆ์„ ๋„ค์ž„ ์ŠคํŽ˜์ด์Šคํ•˜๊ณ  ํŠน์ • ํด๋” / ์ •๊ทœ์‹์œผ๋กœ ์ œํ•œํ•ฉ์‹œ๋‹ค.
  • ํ˜„์žฌ์˜ ์กฐ๋กฑ ๋™์ž‘์ด FB์— ๋Œ€ํ•ด ์—ฌ์ „ํžˆ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. ์ฆ‰, ์„œ๋‘๋ฅด ๊ธฐ ์œ„ํ•ด ํŠน์ • ํด๋”๋ฅผ ํ™”์ดํŠธ๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€ํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ์—๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค ([ ""] ์ง€๊ธˆ์€ ์šฐ๋ฆฌ์—๊ฒŒ)

์„œ๋‘˜๋Ÿฌ ์š”๊ตฌ ์‚ฌํ•ญ์„ ์ดํ•ดํ•˜๊ณ  ์žˆ๋Š”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.
๋‹น์‹ ์ด ์˜๋ฏธํ•˜๋Š” ๊ฒƒ์€ "์ด ๋ชจ๋“ˆ์€ ์„œ๋‘˜๋Ÿฌ ๋ชจ๋“ˆ์ด๋‹ค"๋ผ๊ณ  ๋งํ•  ์ˆ˜์žˆ๋Š” ๊ฐ€๋Šฅ์„ฑ์„์ฃผ๋Š” ๊ฒƒ์ž…๋‹ˆ๊นŒ?
4 ๊ฐœ์˜ ๋ชจ๋“ˆ : /path_1/a , /path_1/b , /path_2/a , /path_2/c ์ด๊ณ  ์„ค์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

"haste_modules:" ["/path_1/a", "/path_2/c"]

/path_1/a ๋ฐ /path_1/b ๋งŒ /path_1 ์—๋งŒ ์กด์žฌํ•˜๋„๋ก ์ œํ•œ๋˜๋ฏ€๋กœ /path_2/c ๋Š” ์œ ํšจํ•˜๋ฉฐ /path_2/a ๋Š” ์˜ค๋ฅ˜ / ๊ฒฝ๊ณ ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

ํƒ€๊ฒŸ์€ ์‹ฑ๊ธ€ / ๋”๋ธ” * ํ•˜๋”๋ผ๋„ ํŠน์ • ํŒŒ์ผ๊ณผ ์ „์ฒด ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์—ฌ์ „ํžˆ ๋…ธ๋“œ ๋ชจ๋“ˆ์„ ๋ชจ์˜ ํ•  ์ˆ˜์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„ ๋‚ด์‹ญ์‹œ์˜ค.

๋‚˜๋Š” ํ˜„์žฌ์˜ ํ–‰๋™์„ ์œ ์ง€ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ชจ์˜ํ•˜๋Š” ๋ชจ๋“ˆ์ด ๋…ธ๋“œ ๋ชจ๋“ˆ (์˜ˆ : fs) ์ธ ๊ฒฝ์šฐ ๋ชจ์˜๋Š” node_modules ํด๋”์™€ ๋™์ผํ•œ ์ƒ์œ„ ๋””๋ ‰ํ† ๋ฆฌ์— ์žˆ์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๋‚ด ์ƒ๊ฐ:

์„œ๋‘˜๋Ÿฌ ๋ชจ๋“ˆ :

haste_modules ์ด ์ข‹๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. collectCoverageFrom ๋ฐ ๊ธฐํƒ€ ์˜ต์…˜ : glob ๋ฐฐ์—ด ๊ณผ ๋˜‘๊ฐ™์ด ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.
๋ชจ๋“  src ๋ฅผ _haste_ ๋ชจ๋“ˆ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ  ํ•˜๋‚˜์˜ ๋””๋ ‰ํ† ๋ฆฌ ๋งŒ ๋น„ ํ—ค์ด์ŠคํŠธ ์ธ ๊ฒฝ์šฐ :

haste_modules: [
  "src",
  "!src/foo"
]

node_modules

@EnoahNetzach ๋ˆ„๊ตฐ๊ฐ€๊ฐ€


์„œ๋‘๋ฅด์ง€ ์•Š๊ณ  ์ž‘๋™ํ•˜๋ ค๋ฉด ... ์Œ, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ค๋ช… ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์–ด์ง„ ๋…ธ๋“œ ๋ชจ๋“ˆ project/node_modules/react , mock์€ project/__node_modules_mocks__/react.js
project/react.js ํŒŒ์ผ์ด์žˆ๋Š” ๊ฒฝ์šฐ project/__mocks__/react.js

(๋ฌผ๋ก  react.js ๊ฐ€ ์˜ˆ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” ๋ชจ๋“  ๋ชจ๋“ˆ ์ค‘ ์–ด๋–ค ํŒŒ์ผ ์ด๋ฆ„๋„ ๊ฐ€๋Šฅํ•˜๋ฉฐ npm ์—์„œ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค)

์ •๋ง๋กœ, node_modules ๋ชจ๋“ˆ์„ ์กฐ๋กฑํ•˜๋Š” node_modules ์กฐ๋กฑ์˜ ๊ฒฝ์šฐ _ugliness_๋ฅผ ๋ณด์ƒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

node_modules ๋‚ด๋ถ€์˜ ๋ชจ๋“ˆ์„ ์ž์ฃผ ์กฐ๋กฑํ•˜๋Š” ์‚ฌ๋žŒ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๋” ์ƒ๊ฐ ํ• ๊นŒ

๋‚ด๊ฐ€ ์•Œ ๋‹ค์‹œํ”ผ ๋ฐ˜์‘ ๋„ค์ดํ‹ฐ๋ธŒ ํ”„๋กœ์ ํŠธ์˜ ๊ฒฝ์šฐ application modules ๋ฅผ ๋ชจ์˜ ์ฒ˜๋ฆฌํ•˜๊ณ  node_modules์˜ ๋ชจ๋“ˆ์„ lodash ).

์ด๊ฒƒ์€ ๋‹ค์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

  • ๊ฐ dumb ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•œ ์ˆ˜๋™ ์ƒ์„ฑ ๋ชจ์˜ ๊ตฌ์„ฑ ์š”์†Œ (dumb ๊ตฌ์„ฑ ์š”์†Œ๋Š” ๋ ˆ์ด์•„์›ƒ ๊ตฌ์„ฑ ์š”์†Œ ์ž„)
  • ๋ชจ๋“  ํ…Œ์ŠคํŠธ ํŒŒ์ผ์—์„œ jest.mock ํ˜ธ์ถœ์˜ ๊ธด ๋ชฉ๋ก

__ ๋‚ด๊ฐ€ ๋งํ•˜๊ณ  ์‹ถ์€ ๊ฒƒ __ : ์ผ๋ถ€ ๊ฒฝ๋กœ์—์„œ ๋ชจ๋“ˆ์„ _auto mock_ํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์žˆ์œผ๋ฉด ๋งค์šฐ ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

config์—์„œ ์ž˜ ์•Œ๋ ค์ง„ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ array-of-jest-globs ๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋ชจ๋“ˆ์„ ํ•„ํ„ฐ๋ง ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹จ๊ณ„๋ณ„๋กœ ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด ๊ตฌ์„ฑ ํ•ญ๋ชฉ์ด ์ฃผ์–ด์ง€๋ฉด

"autoMockingPaths": [
  "src/components/dumb/**/*.js",
]

์ด ์ฝ”๋“œ๋Š” src/screens/app.js .

import _ from 'lodash';
import Button from '../../components/dumb/button.js';

// blah blah AppScreen implementation skipped

src/screens/__tests__/app-test.js ํ™”๋ฉด์— ๋Œ€ํ•œ์ด ํ…Œ์ŠคํŠธ ์ฝ”๋“œ :

import AppScreen from '../app.js';

describe('AppScreen', () => /* testing app screen */);

์šฐ๋ฆฌ๋Š” app-test.js ๋งฅ๋ฝ์—์„œ์ด ์ƒํ™ฉ์— ๋„๋‹ฌํ–ˆ์Šต๋‹ˆ๋‹ค.

  • AppScreen ์€ (๋Š”) ์กฐ๋กฑ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
  • lodash ์€ (๋Š”) ์กฐ๋กฑ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
  • Button ์— ํ•„์š”ํ•œ, AppScreen , ์กฐ๋กฑ๋˜๊ณ 

... automock ๊ตฌ์„ฑ ํ•ญ๋ชฉ์œผ๋กœ ์–ด๋–ป๊ฒŒ ์žฌ์ƒ๋˜๋Š”์ง€ ๋Œ€๋‹ต ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ„๋‹จํžˆ ๋งํ•˜๋ฉด automock: true ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

"autoMockingPaths": [
  "<rootDir>"
]

์ž๋™ ์กฐ๋กฑ ... ์ž ๊น!

automock ๋Œ€ํ•œ ํŠน๋ณ„ํ•œ ๊ฐ€์น˜๋ฅผ ์†Œ๊ฐœ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์ ์–ด๋„ ์‚ฌ๋žŒ๋“ค์˜ ๊ตฌ์„ฑ์„ ๊นจ์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ ๊ตฌ์„ฑ ํ•ญ๋ชฉ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

automock: "app"

jest๋Š” ๋ชจ๋“  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ชจ๋“ˆ์„ ์ž๋™์œผ๋กœ ๋ชจ์˜ํ•˜๊ณ  node_modules ๋ถ€ํ„ฐ ๋ชจ๋“ˆ์˜ ์‹ค์ œ ๋ฒ„์ „์„ ๋‚จ๊น๋‹ˆ๋‹ค.

์•ฑ ๋ ˆ๋ฒจ ๋ชจ๋“ˆ automocking, @cpojer ์— ๋Œ€ํ•ด ์–ด๋–ป๊ฒŒ ์ƒ๊ฐ

"haste_modules" ์ „์ ์œผ๋กœ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ๊ฐœ์ธ์ ์œผ๋กœ automocking์„ ๋งŽ์ด ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ฌด์—‡์ด ๋” ์ข‹์€์ง€ ๋งํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋‚ด ์ถ”์ธก์€ "autoMockingPaths" var๊ฐ€ ์œ ์šฉํ•˜๊ณ  ํƒ„๋ ฅ์  ์ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๋ฐ˜๋Œ€๋กœ ๋‚ด๊ฐ€ ์ฐพ์„ ์ˆ˜ "automock": "app" ๋„ˆ๋ฌด ๋ปฃ๋ปฃํ•œ (๊ธฐ๋ณธ์ ์œผ๋กœ ๋†๋‹ด ์ด๋ฏธ ์žฅ์• ์ธ automocking์„).

__node_modules_mocks__ ๋Š” ์˜ต์…˜์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ €๋Š” ํฌ์†Œ ํ•จ์ด ์ถ”์•…ํ•จ์„ ๋ณด์ƒํ•œ๋‹ค๋Š” ๋ฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค (์ €์˜ ํŠน๋ณ„ํ•œ ๊ฒฝ์šฐ์—๋Š” ๊ฑฐ์˜ node_modules ์กฐ๋กฑํ•˜๋Š” ์ผ์ด ๊ฑฐ์˜ ์—†์œผ๋ฉฐ,ํ•ด์•ผ ํ•  ๋•Œ jest.mock(...) ).
์œ ์ผํ•œ์ฃผ์˜ ์‚ฌํ•ญ์€ ์ค‘์ฒฉ ๋œ node_modules ํด๋” (์˜ˆ : src/node_modules )๊ฐ€์žˆ์„ ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์ผ์ด๋ฉฐ, ์ค‘์ฒฉ ๋œ ๋ฒ„์ „ ์ธ ์ „์—ญ __node_modules_mocks__ ์—์„œ ๋ชจ๋“ˆ์„ ๋ชจ์˜ํ•ด์•ผํ•ฉ๋‹ˆ๊นŒ? ๋˜๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ __mocks__ ํ•จ๊ป˜ ๋ฐฐ์น˜๋ฉ๋‹ˆ๊นŒ?

๋ˆ„๊ตฐ๊ฐ€ node_modules ์™€ app modules ๊ฐ™์€ ๋ชจ๋“ˆ ์ด๋ฆ„์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด ๊ทธ๋ƒฅ ๋˜์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ

app/express.js ๋ฅผ ์•ฑ ๋ชจ๋“ˆ๋กœ ์‚ฌ์šฉ (๋‚ด๊ฐ€ ๊ธฐ์ฐจ ๊ฒŒ์ž„์„ํ•˜๊ณ ์žˆ์„ ์ˆ˜ ์žˆ์Œ)
npm์—์„œ ์›น ์„œ๋ฒ„๋กœ app/node_modules/express
throw new Error("can't mock express.js file - it duplicates one from node_modules")

์ด ๊ฒฝ์šฐ __mocks__ ๋ฅผ node_modules ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๊ฐœ๋ฐœ์ž๋Š” ์ด๋Ÿฌํ•œ ์ถฉ๋Œ์— ๋Œ€ํ•ด ์ž์ฒด ๋ชจ๋“ˆ์˜ ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์•„๋‹ˆ ... ์ด๊ฑด __node_modules_mocks__ ๋ณด๋‹ค ๋” ๋ชป ์ƒ๊ฒผ์ง€?

๋‚ด๊ฐ€ ์˜๋ฏธํ•˜๋Š” ๋ฐ”๋Š” : npm install ed ๋ชจ๋“ˆ x ์ด์ƒ์ด์žˆ๋Š” ๊ฒฝ์šฐ ์ฝ”๋“œ๋ฒ ์ด์Šค์˜ ๋” ๊นŠ์€ ๊ณณ์—์„œ ์ค‘์ฒฉ ๋œ node_modules ํด๋”์— x ๋ชจ๋“ˆ์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ?

๋ช…๋ช… ์ถฉ๋Œ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๋…ธ๋“œ๋ฅผ ์„ ํ˜ธํ•˜์—ฌ ๋…ธ๋“œ์—์„œ ์ฒ˜๋ฆฌ๋˜์ง€๋งŒ ์ด๊ฒƒ์ด ์–ด๋–ป๊ฒŒ ์„œ๋‘˜๋Ÿฌ ์ž‘๋™ํ•˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

Create React App ๊ณผ ๊ฐ™์€ ํ”„๋กœ์ ํŠธ์—์„œ ์‚ฌ์šฉ ์ค‘์ด๊ฑฐ๋‚˜ ๊ฐ€๊นŒ์šด ์žฅ๋ž˜์— ํ•  ์˜ˆ์ •์ด๊ธฐ ๋•Œ๋ฌธ์—์ด ๋ฌธ์ œ๋ฅผ ์ œ๊ธฐํ–ˆ์Šต๋‹ˆ๋‹ค.

์ฐธ๊ณ ๋กœ @cpojer ๋Š”์ด ๋ฌธ์ œ ์™€ ๊ด€๋ จ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์„œ๋‘˜๋Ÿฌ ์ž‘๋™ ๋ฐฉ์‹์„ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฐ ์ค‘์ ์„ ๋‘๋„๋กํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค (๊ธฐ๋ณธ ์„ค์ •์ด ์•„๋‹Œ ํ™”์ดํŠธ๋ฆฌ์ŠคํŠธ / ๋ธ”๋ž™๋ฆฌ์ŠคํŠธ). ๋‚˜๋Š” <rootDir>/__mocks__ ์ด ๋…ธ๋“œ ๋ชจ๋“ˆ ๋ชจ์˜ ๊ธฐ๋ณธ๊ฐ’์ด์–ด์•ผํ•œ๋‹ค๊ณ  ์œ ์ง€ํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ๊ตฌ์„ฑ ์˜ต์…˜์œผ๋กœ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค : "globalMocks"๊ธฐ๋ณธ๊ฐ’์€ <rootDir>/__mocks__ ์ž…๋‹ˆ๋‹ค. ๋ˆ„๊ตฌ๋“ ์ง€ ์ด๊ฒƒ์— ๋Œ€ํ•ด ๊ธฐ๊บผ์ด ๋…ธ๋ ฅํ•ฉ๋‹ˆ๊นŒ?

๋‹ค์Œ ์ฃผ๋ง๋ณด๋‹ค ๋นจ๋ฆฌ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ ํ•  ์ˆ˜์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๋ฒˆ ์ผ์š”์ผ์— PR ์ž‘์—…์„ ํ•  ์ˆ˜์žˆ์–ด, ๋‚˜๋Š” ์ข€ ์ž์œ  ๋กญ๋‹ค

์š”์•ฝํ•˜๊ธฐ ์œ„ํ•ด @cpojer- <rootDir>/__mocks__ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ globalMocks ๊ตฌ์„ฑ ํ•ญ๋ชฉ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ด ์˜ต์…˜์€ ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•˜์—ฌ jest ๋‚ด์—์„œ node-haste ์‚ฌ์šฉ์„ ๊ทœ์ œํ•ฉ๋‹ˆ๋‹ค. ์•„๋‹ˆ๋ฉด ๊ฒฝ๋กœ์˜ ๋ฐฐ์—ด์ผ๊นŒ์š”?

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ์œ„ํ•œ ๋” ํฐ ๋ณ€ํ™”๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ, ๋‹จ์ˆ˜ globalMocks ์˜ต์…˜ (๋ฌธ์ž์—ด ๋˜๋Š” ๋ฌธ์ž์—ด ๋ฐฐ์—ด ์ผ ์ˆ˜ ์žˆ์Œ)๊ณผ haste ๋ชจ๋“ˆ ๊ฒฝ๋กœ ๋ฐฐ์—ด ์ธ hasteModules ์˜ต์…˜์ด ๋ชจ๋‘ ํ•„์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด ์ฝ”๋“œ์˜ ๋Œ€๋ถ€๋ถ„์€ jest-haste-map ๋ฐ jest-resolve์— ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ฌ๋ฐ”๋ฅธ ์†”๋ฃจ์…˜์ด ์•„์ง ์–ด๋–ค ๋ชจ์Šต ์ผ์ง€ 100 % ํ™•์‹ ํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.


๋ณด๋‚ธ ์‚ฌ๋žŒ : Max Sysoev [email protected]
์ „์†ก : 2016 ๋…„ 12 ์›” 9 ์ผ ๊ธˆ์š”์ผ ์˜ค์ „ 8:18:44
๋ฐ›๋Š” ์‚ฌ๋žŒ : facebook / jest
์ฐธ์กฐ : Christoph Pojer; ์–ธ๊ธ‰ํ•˜๋‹ค
์ œ๋ชฉ : Re : [facebook / jest] [bug] ์ค‘๋ณต ๋œ ์ˆ˜๋™ ๋ชจ์˜๊ฐ€ ๋ณ„๋„์˜ ๋””๋ ‰ํ† ๋ฆฌ์— ์žˆ์Œ (# 2070)

๋‚˜๋Š” ์ด๋ฒˆ ์ผ์š”์ผ์— PR ์ž‘์—…์„ ํ•  ์ˆ˜์žˆ์–ด, ๋‚˜๋Š” ์ข€ ์ž์œ  ๋กญ๋‹ค

@cpojer https://github.com/cpojer ์š”์•ฝํ•˜๊ธฐ-๊ธฐ๋ณธ๊ฐ’์œผ๋กœ globalMocks ๊ตฌ์„ฑ ํ•ญ๋ชฉ ๋งŒ๋“ค๊ธฐ/ __ mocks__. ์ด ์˜ต์…˜์€ ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•˜์—ฌ jest ๋‚ด์—์„œ ๋…ธ๋“œ ํ—ค์ด์ŠคํŠธ ์‚ฌ์šฉ์„ ๊ทœ์ œํ•ฉ๋‹ˆ๋‹ค. ์•„๋‹ˆ๋ฉด ๊ฒฝ๋กœ์˜ ๋ฐฐ์—ด์ผ๊นŒ์š”?

-
๋‹น์‹ ์ด ์–ธ๊ธ‰ ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐ›๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ฑฐ๋‚˜ GitHub https://github.com/facebook/jest/issues/2070#issuecomment-265958606 ์—์„œ ๋ณด๊ฑฐ๋‚˜ https://github.com/notifications/unsubscribe-auth/AAA0KAMFc34iKqBDLHZzgaGHqyc3WkAzks5rGQ7kgaJpZM4Kt2DW .

์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ์ œ ์›Œํฌ ์Šคํ…Œ์ด์…˜์ด ๊ณ ์žฅ ๋‚ฌ๊ณ  ๋ช‡ ๋‹ฌ (1 ~ 2 ๊ฐœ์›”) ์•ˆ์— ์ž‘๋™ ํ•  ๋ฐฉ๋ฒ•์ด์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด PR์— ๋Œ€ํ•œ ํ”„๋กœ์ ํŠธ๋„ ์žƒ์–ด ๋ฒ„๋ ธ์Šต๋‹ˆ๋‹ค.

getMockName ์˜ ๋™์ž‘์„ ๋ณ€๊ฒฝํ•˜๋Š” ๊ตฌ์„ฑ ์˜ต์…˜

๋†๋‹ด์˜ ๋‚ด๋ถ€์— ๋„ˆ๋ฌด ์ต์ˆ™ํ•˜์ง€๋Š” ์•Š์ง€๋งŒ FB์— ๋Œ€ํ•œ ๋†๋‹ด์„ ๊นจ์ง€ ์•Š๊ณ  ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ํ•ด๊ฒฐ์ฑ… ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์›๋ž˜ ์ƒ๊ฐํ–ˆ๋˜ ๊ฒƒ๋ณด๋‹ค ๋” ๋ณต์žก ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜์—๊ฒŒ ์ˆ˜๋™ ๋ชจ์˜๋Š” ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ํŒŒ์ผ์„ ๋Œ€์ฒดํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ™์€:

{ 'aws-sdk': '/Users/project/__mocks__/aws-sdk.js',
  'slack': '/Users/project/__mocks__/slack.js',
  '/Users/project/db/index': '/Users/project/db/__mocks__/index.js',
  '/Users/project/slack/index': '/Users/projects/slack/__mocks__/index.js' }

require('aws-sdk') ๋ฐ›๋Š” ํ•ด๊ฒฐํ•ด์•ผ /Users/project/__mocks__/aws-sdk.js ์ด๊ฐ€์— ๋Œ€ํ•œ ๋ชจ์˜์ž…๋‹ˆ๋‹ค node_module .

require('./db') (๋˜๋Š” db ๋Œ€ํ•œ ๋ชจ๋“  ๊ฒฝ๋กœ)๋Š” /Users/project/db/__mocks__/index.js ํ•ฉ๋‹ˆ๋‹ค.

jest ์ˆ˜๋™ ๋ชจ์˜๋ฅผ ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๋‚˜์˜ ์ดํ•ด๋Š” (์œ„์™€ ๊ฐ™์€ ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์•„๋งˆ๋„ ๋” ๋งŽ์€ ๋ฌธ์„œ๊ฐ€์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค) __mocks__ ๋””๋ ‰ํ† ๋ฆฌ ๋‚ด์—์„œ ๊ฐ€๋Šฅํ•œ ํ•œ ๋ชจ์˜๋˜๋Š” ํŒŒ์ผ์— ๊ฐ€๊นŒ์›Œ ์•ผํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ˆ˜๋™ ๋ชจ์˜๋Š” ๋ชจ๋“ˆ ๋ฐ”๋กœ ์˜†์—์žˆ๋Š” __mocks __ / ํ•˜์œ„ ๋””๋ ‰ํ† ๋ฆฌ์— ๋ชจ๋“ˆ์„ ์ž‘์„ฑํ•˜์—ฌ ์ •์˜๋ฉ๋‹ˆ๋‹ค. (https://facebook.github.io/jest/docs/manual-mocks.html)

์ด๋ฅผ ๊ฐ์•ˆํ•  ๋•Œ ์œ„์˜ ํ–‰๋™์ด ๊ฐ€์žฅ ์˜๋ฏธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์ƒ๊ฐ?

์ด๊ฒƒ์€ ์œ„์™€ ๊ฐ™์€ ๊ฒƒ์„ ๊ตฌํ˜„ํ•˜๋Š” ์ดˆ๊ธฐ ๋‹จ๊ณ„์ž…๋‹ˆ๋‹ค : https://github.com/facebook/jest/compare/master...mhahn : issue-2070-new-mock-resolution

๋” ์ด์ƒ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ˆœ์ˆ˜ํ•œ "์ด๋ฆ„์ด ์ง€์ •๋œ"๋ชจ์˜๋ฅผ ํ—ˆ์šฉํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋Œ€๋ถ€๋ถ„์˜ jest ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ค‘๋‹จํ•ฉ๋‹ˆ๋‹ค. https://github.com/facebook/jest/blob/master/packages/jest-runtime/src/__mocks__/ createRuntime.js

createRuntime ์™€ ๊ฐ™์€ IMO๋Š” ํ…Œ์ŠคํŠธ ์œ ํ‹ธ๋ฆฌํ‹ฐ ํด๋”์— ์žˆ์–ด์•ผํ•˜๋ฉฐ ํ•„์š”ํ•œ ํ…Œ์ŠคํŠธ์—์„œ ๊ฐ€์ ธ์™€์•ผํ•˜๋Š” ํ…Œ์ŠคํŠธ ์œ ํ‹ธ๋ฆฌํ‹ฐ์ž…๋‹ˆ๋‹ค. ์ˆ˜๋™ ๋ชจ์˜๋กœ ๊ตฌํ˜„๋˜๋Š” ๋ฐฉ์‹์€ ๋ณด์กด๋˜์–ด์•ผํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์ €์—๊ฒŒ ์ดํ•ด๊ฐ€๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํ•œ ๊ฐ€์ง€ ์˜ต์…˜์€ ๊ธฐ์กด ๋™์ž‘๊ณผ ์œ„์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ •๋ฆฌ ํ•œ ๋ฒ„์ „ ์‚ฌ์ด๋ฅผ ์ „ํ™˜ํ•˜๋Š” ๊ตฌ์„ฑ ๋ณ€์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ๋ฌด์—‡์„ ๋ถˆ๋Ÿฌ์•ผํ•˜๋Š”์ง€ ์ •๋ง๋กœ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” Facebook์—์„œ ๊ทน๋„๋กœ ์˜์กดํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ˜„์žฌ์˜ ํ–‰๋™์„ ๊นจ๋œจ๋ฆด ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

@cpojer ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. https://github.com/facebook/jest/issues/2070#issuecomment -265027510 ์ฝ”๋“œ๋ฅผ ์ฝ์€ ํ›„์ด ์ฃผ์„์„ ์‹ค์ œ๋กœ ์ดํ•ดํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ๋™์ž‘์„ ํ•ด๊ฒฐํ•  ๋””๋ ‰ํ† ๋ฆฌ ๋ชฉ๋ก์„ ํ—ˆ์šฉ ๋ชฉ๋ก์— ์ถ”๊ฐ€ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

๋‘ ๊ฐ€์ง€ ์ƒˆ๋กœ์šด ๊ตฌ์„ฑ ์˜ต์…˜์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

  • fullPathMockResolution (๊ธฐ์กด ๋™์ž‘์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๊ธฐ๋ณธ๊ฐ’์€ false )
    ๊ฒฐํ•ฉ:
  • namedMockDirectories : fullPathMockResolution ๊ฐ€ ํ™œ์„ฑํ™”๋˜๋ฉด ํ•ด๋‹น ๋ฐฐ์—ด ๋‚ด์˜ ๋ชจ๋“  ๋””๋ ‰ํ„ฐ๋ฆฌ๊ฐ€ ๊ธฐ์กด ๋™์ž‘์œผ๋กœ ํ™•์ธ๋ฉ๋‹ˆ๋‹ค. FB ์‚ฌ์šฉ ์‚ฌ๋ก€์˜ ๊ฒฝ์šฐ ์œ„์—์„œ ์–ธ๊ธ‰ ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ [<rootDir>] ๋ฉ๋‹ˆ๋‹ค.

์ด๋ฅผ ํ†ตํ•ด ๊ฐœ๋ฐœ์ž๋Š” ์ „์ฒด ๊ฒฝ๋กœ ํ™•์ธ์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๊ธฐ์กด jest ์„ค์น˜์— ์˜ํ•œ ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•˜์ง€ ์•Š์œผ๋ฉฐ ์›ํ•˜๋Š” ๊ฒฝ์šฐ ํŠน์ • ๋””๋ ‰ํ† ๋ฆฌ์— ๋Œ€ํ•œ ๊ธฐ์กด ๋™์ž‘์„ ํ™œ์„ฑํ™” ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

cc @voideanvalue ์ด๊ฒƒ์€ ๋‹น์‹ ์ด ์ƒ๊ฐํ•ด์•ผ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค (์ƒˆ๋กœ์šด ์„œ๋‘˜๋Ÿฌ ๊ตฌํ˜„์˜ ์ผ๋ถ€๋กœ ๋„ค์ž„ ์ŠคํŽ˜์ด์Šค ๋งค๋‰ด์–ผ ๋ชจ์˜).

+1,์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ?

+1

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ๋ฅผ ๋”ฐ๋ฅด๋ฉด ์ •๋ง ๊ณ ํ†ต ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค.

project/
โ”œโ”€โ”€ models
โ”‚   โ”œโ”€โ”€ index.js
โ”‚   โ”œโ”€โ”€ __mocks__/
โ”‚   โ”‚   โ”œโ”€โ”€ index.js/
โ”œโ”€โ”€ challenges
โ”‚   โ”œโ”€โ”€ index.js
โ”‚   โ”œโ”€โ”€ __mocks__/
โ”‚   โ”‚   โ”œโ”€โ”€ index.js/

๊ฒฝ๋กœ๋ฅผ ๊ณ ๋ คํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‹ค์ œ๋กœ ์ถฉ๋Œํ•˜๋Š” ์ด๋ฆ„์ด ์—†๋Š”๋ฐ๋„ '์ถฉ๋Œํ•˜๋Š”'์ด๋ฆ„์„ ๊ฐ€์ง„ ๋‘ ๊ฐœ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ํ…Œ์ŠคํŠธ์—์„œ ๋ชจ๋“ˆ์„ ์ˆ˜๋™์œผ๋กœ ๋ชจ์˜ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๊ฑด๋ฐฐ,
๋„๋ฏธ๋‹‰

@cpojer ์—ฌ๊ธฐ์— ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๋‚˜๋ฅผ์œ„ํ•œ ์•ฝ๊ฐ„์˜ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ require๋กœ ๋ชจ๋“ˆ์„ ์กฐ๋กฑํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

jest.mock('models/index', () => require('models/index/_mocks_/index'));

jest๊ฐ€ ํŒŒ์ผ์„ ์žก์ง€ ๋ชปํ•˜๋„๋ก __mocks__ ํด๋” ์ด๋ฆ„์„ _mocks_ .

์ด๊ฒƒ์ด ์ž‘๋™ํ•˜๋Š” ์–ด๋Š ๋‚  _mocks_ ์„ __mocks__ ๋กœ ๋ฐ”๊พธ๊ณ  jest.mock์—์„œ require ๋ถ€๋ถ„์„ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

์ฒซ์งธ, ๋ชจ๋“  ๋ฉ‹์ง„ ์ž‘์—…์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.
๋‘˜์งธ : ์ด๊ฒƒ์€ ์ •๋ง, ๋งค์šฐ ์‹ค๋ง ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. ๋ชจ์˜ ํŒŒ์ผ์ด ๋ชจ์˜๋˜๋Š” ์ „์ฒด ์ฝ”๋“œ๋ฒ ์ด์Šค์˜ ๋‹ค๋ฅธ ํŒŒ์ผ๊ณผ ์ด๋ฆ„์„ ๊ณต์œ  ํ•  ๋•Œ ํ…Œ์ŠคํŠธ ํŒŒ์ผ์—์„œ jest.mock์„ ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜ธ์ด ์ŠคํŒ…์€ ์‹ค์ œ ๋ชจ์˜ ๊ฐ€์ ธ ์˜ค๊ธฐ๋„ ํ—ˆ์šฉํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ํ•ด๋‹น ํŒŒ์ผ์„ ๋ชจ์˜ํ•ด์•ผํ•˜๋Š” ๋‘ ํ…Œ์ŠคํŠธ์—์„œ ๋ชจ์˜๋ฅผ ๋ณต์ œํ•ด์•ผํ•˜๋ฏ€๋กœ ํ…Œ์ŠคํŠธ ์Šค์œ„ํŠธ์˜ ์ทจ์•ฝ์„ฑ์ด ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๊ณ ํ•ฉ๋‹ˆ๊นŒ? FB๋Š”์ด ๋ฌผ๊ฑด์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๊นŒ? ๊ทธ๋ ‡๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ? ๐Ÿ˜ž

์ด ๊ฒฝ๊ณ ๋ฅผ๋ณด๊ณ  ๋งค์šฐ ์‹ค๋ง ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. ์ˆ˜์ •์„ ๊ธฐ๋‹ค๋ฆด ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ๊ฐ€์ง„ ๋ฌธ์ œ๋Š” ๊ด€๋ จ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

jest.mock ( 'src / utils / history')๊ฐ€ ์žˆ์œผ๋ฉด 'history'node_module๋„ ์ž˜๋ชป ์กฐ๋กฑํ•ฉ๋‹ˆ๋‹ค.

https://github.com/cwmoo740/jest-manual-mocks-node-modules

์–˜๋“ค ์•„ ์–ด๋–ค ์—…๋ฐ์ดํŠธ?

@masoudcs ๋‚˜๋Š” ์ด๊ฒƒ์ด ๊ฒฝ๊ณ ๋ฅผ ์ œ๊ฑฐํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

package.json

"jest": {
  /* other settings ... */
  "modulePathIgnorePatterns": ["<rootDir>/node_modules/react-native/Libraries/Core/__mocks__"]
}

modulePathIgnorePatterns ๋ฐฐ์—ด์— "์ค‘๋ณต"ํด๋”๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๊ฒฝ๊ณ ๊ฐ€ ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค.

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค @brunolm

๊ทธ๋ž˜์„œ ๊ทธ๊ฒƒ์€ ๋‹จ์ง€ ๊ฒฝ๊ณ ์ž…๋‹ˆ๋‹ค, ๋งž์Šต๋‹ˆ๊นŒ?!
๋‚˜๋Š” ์ด๊ฒƒ์ด ๋‚˜์œ ์ผ์ด ์ผ์–ด๋‚˜์ง€ ์•Š๋„๋กํ•˜๊ณ  ์‹ถ๋‹ค. ์ฆ‰, ์—ฌ๋Ÿฌ ๋””๋ ‰ํ† ๋ฆฌ์—์„œ index.js๋ฅผ ์กฐ๋กฑํ•˜๋Š” ๊ฒƒ
src/app/modules/module1/__mocks__/index.js ๋ฐ src/app/modules/module2/__mocks__/index.js

๊ทธ๊ฒŒ ์ค‘์š”ํ•œ์ง€๋Š” ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ ์‹คํ–‰ ์ค‘์—๋Š” ๋‹ค๋ฅธ ํ•˜๋‚˜๋งŒ ์„ ํƒํ•œ๋‹ค๊ณ  ๋งํ–ˆ๊ณ  ๋‚ด๊ฐ€ ๋‚˜์—ดํ•œ ๊ฒƒ์€ ์–ด๋Š ์ชฝ์ด๋“  ๋ฌด์‹œํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ๋ฌด์‹œํ•˜๋ผ๊ณ ํ•ด๋„ ๊ดœ์ฐฎ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์–ด์ฐจํ”ผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

์˜ˆ, ๋ง์”€ํ•˜์‹ ๋Œ€๋กœ, ์ง€๊ธˆ๊นŒ์ง€ ์•„๋ฌด๋Ÿฐ ๋ฌธ์ œ๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.
๋ฐ”๋ผ๊ฑด๋Œ€, ๊ทธ๊ฒƒ์€ํ•ด์•ผ ํ•  ์ผ์„ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค! :)
๊ฐ์‚ฌ

์ด ๋งˆ์ง€๋ง‰ ๋‘ ์ปค๋ฐ‹์ด ์ œ์•ˆํ•œ ๊ฒƒ์„ ์‹œ๋„ํ–ˆ์ง€๋งŒ ๊ฒฝ๊ณ ๋ฅผ ์ œ๊ฑฐํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

jest.mock('dir/index', () => require('dir/__mocks_/index'));

๋‚ด ๊ตฌ์„ฑ์— testPathIgnorePatterns: ['/_book/', ...otherStuff] ์ด ์žˆ์ง€๋งŒ GitBook ( ./_book ๋””๋ ‰ํ„ฐ๋ฆฌ)์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์—์ด ๊ฒฝ๊ณ ๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ›‘์–ด ๋ณด๋ฉด์„œ ๋ช…ํ™•ํ•œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ฒฝ๊ณ  ํ‘œ์‹œ๋ฅผ ์ค‘๋‹จํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ๋„์›€์„ ์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

+1

์ด๊ฒƒ์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

๋˜ํ•œ ์œ„์—์„œ ์ œ์•ˆํ•œ ๋” ๋”๋Ÿฌ์šด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋‚ด ํ…Œ์ŠคํŠธ ํŒŒ์ผ์„ ์ •๊ธฐ์ ์œผ๋กœ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ์ˆ˜์ • ์‚ฌํ•ญ์„ ์ฐพ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

jest.mock('models/index', () => require('models/index/_mocks_/index'));

์šฐ๋ฆฌ์˜ ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ๋Š” ์—ฌ๊ธฐ๋ฅผ ์ฐธ์กฐ s์˜ '@dkundel ๊ฐ™์€ ๋ชจ์–‘ https://github.com/facebook/jest/issues/2070#issuecomment ์™€ ์ž์‹ ์˜ ๋„ค์ž„ ์ŠคํŽ˜์ด์Šค์—์„œ ๋ชจ๋ธ๊ณผ ๊ตฌ์„ฑ ์š”์†Œ์™€ -301332202 index.js ๊ธฐ๋ณธ ์ธ ์ˆ˜์ถœ.

๊ฒฝ๊ณ ๋ฅผ ์นจ๋ฌต ์‹œํ‚ค๊ฑฐ๋‚˜ ๋ชจ๋“  ๋ชจ์˜๋ฅผ ํ”Œ๋žซ ๋””๋ ‰ํ† ๋ฆฌ์— ๋˜์ง€์ง€ ์•Š๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ถ€ ๋ชจ์˜๋Š” ๊นŠ๊ฒŒ ์ค‘์ฒฉ๋˜์–ด ์žˆ์œผ๋ฉฐ ์ œ์•ˆ ๋œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
jest.mock('pages/index/components/Component', () => require('pages/index/components/Component/_mocks_/index'));
์šฐ๋ฆฌ ๊ตฌ์กฐ์—์„œ.

ํ•œ๋งˆ๋””?

@karomancer ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒฝ๊ณ ๋ฅผ ์ œ๊ฑฐ ํ•  ์ˆ˜์žˆ๋Š” PR # 6037์„ ์ œ์ถœํ–ˆ์Šต๋‹ˆ๋‹ค. ์•„์ง์€ ๋ณ‘ํ•ฉ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๊ธฐ์—ฌ์ž์˜ ์‘๋‹ต์„ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋Š” ๋งค์šฐ ์‹ค๋ง ์Šค๋Ÿฝ์ง€๋งŒ ๋” ๊น”๋”ํ•œ ๋ช…๋ช… ๊ทœ์น™์„ ๋งŒ๋“œ๋Š” ์ข‹์€ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์ฐพ์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

package.json

{
  "jest": {
    "setupFiles": [
      "<rootDir>/test.mocks.ts"
    ]
  }
}
/* test.mocks.ts */

// modules mocked before every test
// use `jest.unmock(...)` to undo for any single test case
const mockedModules = [
    "./path/to/module1/index.ts",
    "./path/to/module2/index.ts",
];

mockedModules.forEach((path) => {
    const mockPath = path.replace(/\.ts$/g, ".mock.ts");
    jest.mock(path, () => require(mockPath));
});

์ด๋ ‡๊ฒŒํ•˜๋ฉด anything.mock.ts ํ˜•์ œ๋ฅผ ๋งŒ๋“ค๊ณ  ์ตœ์ƒ์œ„ test.mocks ์˜ mockedModules ๋ฐฐ์—ด์—์„œ ์›๋ณธ ๊ฒฝ๋กœ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ anything.ts ๋ฅผ ๋ชจ์˜ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๊ฐ€ ๊ฐœ์„  ์‚ฌํ•ญ์œผ๋กœ ํ‘œ์‹œ๋œ ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

์ด๊ฒƒ์€ ๋‚˜๋ฅผ ์œ„ํ•ด ์ผํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. jest.config.js์—์„œ :

module.exports = {
  // ...
  modulePathIgnorePatterns: ["<rootDir>/.*/__mocks__"]
};

์ž‘์€ ํ”„๋กœ์ ํŠธ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—์ด ๋ณ€๊ฒฝ์˜ ๋ฒ”์œ„ ๋‚˜ ์˜ํ–ฅ์„ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

@amccloud ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ์ด๊ฒƒ์€ ๋‚ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค! ์•„๋ž˜ ์„ธ๋ถ€ ์ •๋ณด.

๋‚ด ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ ๋””๋ ‰ํ† ๋ฆฌ์— helpers ๋ชจ๋“ˆ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋„์šฐ๋ฏธ๊ฐ€ parseNodeFromString ํ•จ์ˆ˜๋ฅผ ๋‚ด๋ณด๋‚ด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
๋‹ค๋ฅธ ๋ชจ๋“ˆ ๋กœ์ปฌ ํŒŒ์ผ helpers ์—์„œ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ํ…Œ์ŠคํŠธ ์ค‘ ํ•˜๋‚˜๋ฅผ ์กฐ๋กฑํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  parseNodeFromString ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ํ…Œ์ŠคํŠธ๊ฐ€ ๋‹ค์Œ ์˜ค๋ฅ˜์™€ ํ•จ๊ป˜ ์‹คํŒจํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค.

FAIL  src/some_dir/bla/tests/SomeClass.test.js
  โ— Test suite failed to run

    TypeError: (0 , _helpers.parseNodeFromString) is not a function

์ด ๋ฌธ์ œ๋Š” ์–ด๋–ป์Šต๋‹ˆ๊นŒ? @amccloud ์†”๋ฃจ์…˜์ด ์˜ฌ๋ฐ”๋ฅธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

modulePathIgnorePatterns: ["<rootDir>/.*/__mocks__"]

์ด ์†”๋ฃจ์…˜์€ ๋…ธ๋“œ ๋ชจ๋“ˆ์— ๋Œ€ํ•œ ์ตœ์ƒ์œ„ ๋ชจ์˜๊ฐ€ ์‹คํŒจํ•˜๋”๋ผ๋„ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ "modulePathIgnorePatterns": ["<rootDir>/src/react/.*/__mocks__"], ๋ฃจํŠธ __mock__ ํด๋”๋ฅผ ๋ฌด์‹œํ•˜์ง€ ์•Š๋„๋ก ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ์ „ํžˆ mock์ด ๋ฃจํŠธ์˜ ์ „์ฒด ๊ฒฝ๋กœ ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ณ ์œ ํ•˜์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์€ ๋งค์šฐ ์ด์ƒํ•ฉ๋‹ˆ๋‹ค. users/helper.js & posts/helper.js ๋Š” ๋งค์šฐ ์ผ๋ฐ˜์ ์ž…๋‹ˆ๋‹ค. ๊ฒฝ๊ณ ๋Š” ์ƒ๋‹นํ•œ ๊ณต๊ฐ„์„ ์ฐจ์ง€ํ•˜๋ฉฐ ์‹ค์ œ ๊ฒฝ๊ณ ๋ฅผ ์™„์ „ํžˆ ์ˆจ๊ธฐ๊ณ  ์‹ถ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด PR์˜ ํ˜„์žฌ ์ƒํƒœ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์ ์ ˆํ•œ ํ•ด๊ฒฐ์ฑ…์ด๋‚˜ ํ•ดํ‚น์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์ œ ๊ฒฝ์šฐ์—๋Š” ๋ชจ์˜ ๋ชจ๋“ˆ์ด ๋ชจ๋“  ๋นŒ๋“œ์™€ ํ•จ๊ป˜ Dist ๋””๋ ‰ํ† ๋ฆฌ์— ๋ณต์‚ฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ typescript๊ฐ€ ๋” ๊นŠ์€ dir ๊ตฌ์กฐ์— ์†ํ•˜๋Š” ๊ฒฝ๋กœ / ํŒจํ„ด์„ ์ œ์™ธ ํ•  ์ˆ˜์—†๋Š” ๋ฌธ์ œ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์—ฌ์ „ํžˆ "typescript@^3.4.5"์— ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋ชจ๋“  ํ…Œ์ŠคํŠธ ์‹คํ–‰ ์ „์— "rimraf dist"๋กœ Dist ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์ฒญ์†Œํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค.

"test:unit": "npm run clean && stencil test --spec --snapshot",

๋‚˜๋Š” ํ•ดํ‚น์ด๋ผ๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์ง€๋งŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์ด๋ด ๋‚ด๊ฐ€ ์—ฌ๊ธฐ์—์„œ ์ผ์–ด๋‚œ ์ผ์„ ํ•ด๊ฒฐํ–ˆ์œผ๋ฉฐ ์•„๋งˆ๋„ ์ด๊ฒƒ์„ ๋ณต์ œํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์„ธ ๊ฐ€์ง€ ์†”๋ฃจ์…˜ ๋˜๋Š” ์‹œ๋‚˜๋ฆฌ์˜ค :

1, ํ…์ŠคํŠธ ํŽธ์ง‘๊ธฐ์—์„œ ๋‚ด ์•ฑ์„ ๋‘ ๋ฒˆ ํŽธ์ง‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ๋‘ ๊ฐœ์˜ ๋‹ค๋ฅธ ์ฐฝ์—์„œ pod ์„ค์น˜ / ์—…๋ฐ์ดํŠธ ๋ฐ react-native run-ios๋ฅผ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ Xcode์™€ ๋‚ด ์•ฑ์—์„œ ์ค‘๋ณต ํŒŒ์ผ์„ ๊ฒ€์ƒ‰ํ–ˆ์ง€๋งŒ ์ฐพ์„ ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ ์•ฑ์„ ์‚ญ์ œํ•˜๊ณ  react-native run-ios๋ฅผ ๋‹ค์‹œ ์‹คํ–‰ํ–ˆ๋Š”๋ฐ ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‘ ๊ฐœ์˜ node_modules๊ฐ€ ๋‚ด scr ํŒŒ์ผ์—์„œ node_modules์™€ node_modules0๊ณผ ๊ฐ™์ด ๋ณต์ œ ๋œ ๊ฒƒ์œผ๋กœ ๋‚˜ํƒ€๋‚ฌ์Šต๋‹ˆ๋‹ค.

2, ๋•Œ๋•Œ๋กœ ๋‚ด Mac์—์„œ ์ž„์˜์˜ ํ‚ค๋ฅผ ๋ˆ„๋ฅด๋ฉด node_modules๊ฐ€ ์˜ˆ๋ฅผ ๋“ค์–ด SRC ํด๋”์— ๋ณต์ œ๋˜๋ฏ€๋กœ์ด ๊ฒฝ์šฐ์—๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ด๋ฏ€๋กœ ํด๋”์—์„œ node_modules ์ค‘๋ณต์„ ์‚ดํŽด ๋ณด๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

3, ๋™์ผํ•œ ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ ๋‹ค๋ฅธ ์•ฑ์„ ์‹œ์ž‘ํ•˜๊ณ  ์ข…๋ฃŒ ํ•  ๋•Œ๊นŒ์ง€ ์•ฑ์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ค‘๋ณต ๋œ ์•ฑ์„ ์žฌ๋ถ€ํŒ… ํ•œ ๋‹ค์Œ ์˜ค๋ฅ˜์—†์ด ์‹คํ–‰๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์•„์ง๋„ ์•„๋ฌด๊ฒƒ๋„? CRA์—์„œ modulePathIgnorePatterns๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

3 ๋…„ 10 ๊ฐœ์›”

๋˜๋Š” ๊ฒฝ๊ณ  ๋งŒํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ์ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ Jest๊ฐ€ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ ์‹œํ‚ค๋„๋ก ๊ฐ•์ œ ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฒฝ๊ณ ๋Š” ์‰ฝ๊ฒŒ ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค. ๋‚ด ํ”„๋กœ์ ํŠธ์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•˜๋ฏ€๋กœ์ด๋ฅผ ๋„์ž… ํ•œ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ฒ˜๋ฆฌํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰