การทดสอบแอปพลิเคชัน Angular โดยใช้ Jest - Jest พบโทเค็นที่ไม่คาดคิด

Aug 17 2020

ฉันใช้ Jest เพื่อทดสอบแอปพลิเคชัน Angular แต่ได้รับข้อผิดพลาดต่อไปนี้:

● Test suite failed to run

    Jest encountered an unexpected token

    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

    Here's what you can do:
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    /home/cxo/Projects/git/sparta/clients/vaph/node_modules/@ckeditor/ckeditor5-watchdog/src/editorwatchdog.js:12
    import { throttle, cloneDeepWith, isElement } from 'lodash-es';
           ^

    SyntaxError: Unexpected token {

      at Runtime.createScriptFromCode (../../../node_modules/jest-runtime/build/index.js:1258:14)
      at ../../../node_modules/@ckeditor/ckeditor5-angular/bundles/ckeditor-ckeditor5-angular.umd.js:2:85
      at Object.<anonymous> (../../../node_modules/@ckeditor/ckeditor5-angular/bundles/ckeditor-ckeditor5-angular.umd.js:5:2)

ฉันยังใช้ https://nx.dev/angular.

นี่คือการกำหนดค่า jest ของฉัน:

module.exports = {
  testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'],
  transform: {
    '^.+\\.(ts|js|html)$': 'ts-jest',
  },
  resolver: '@nrwl/jest/plugins/resolver',
  moduleFileExtensions: ['ts', 'js', 'html'],
  coverageReporters: ['html'],
};

package.json ของฉันดูเหมือนว่า:

{
  "name": "App-Name",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": {
    "ng": "ng",
    "nx": "nx",
    "start": "ng serve",

   // SEVERAL ENTRIES ARE OMITTED FOR CLARITY  
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^9.1.12",
    "@angular/cdk": "~9.2.4",
    "@angular/common": "^9.1.12",
    "@angular/compiler": "^9.1.12",
    "@angular/core": "^9.1.12",
    "@angular/forms": "^9.1.12",
    "@angular/localize": "~9.1.12",
    "@angular/material": "~9.2.4",
    "@angular/material-moment-adapter": "^9.2.4",
    "@angular/platform-browser": "^9.1.12",
    "@angular/platform-browser-dynamic": "^9.1.12",
    "@angular/router": "^9.1.12",
    "@angular/service-worker": "~9.1.12",
    "@auth0/angular-jwt": "^4.1.2",
    "@babel/polyfill": "^7.10.4",
    "@ckeditor/ckeditor5-angular": "^1.2.3",
    "@ckeditor/ckeditor5-build-balloon": "^19.0.0",
    "@ckeditor/ckeditor5-build-balloon-block": "^19.0.0",
    "@ckeditor/ckeditor5-build-classic": "^19.0.0",
    "@ckeditor/ckeditor5-build-decoupled-document": "^19.0.0",
    "@ckeditor/ckeditor5-build-inline": "^19.0.0",
    "@nrwl/angular": "9.5.1",
    "angular-build-info": "^1.0.7",
    "angular-notifier": "^6.0.1",
    "core-js": "^2.5.4",
    "file-saver": "^2.0.2",
    "ng2-file-upload": "^1.4.0",

    // SEVERAL ENTRIES ARE OMITTED FOR CLARITY  

    "secure-ls": "^1.2.6",
    "zone.js": "^0.10.2"
  },
 "devDependencies": {
     "@angular-devkit/build-angular": "^0.901.11",
     "@angular/cli": "^9.1.11",
     "@angular/compiler-cli": "^9.1.12",
     "@angular/language-service": "^9.1.12",
     "@compodoc/compodoc": "^1.1.11",
     "@ngneat/spectator": "^5.12.0",
     "@nrwl/cypress": "9.5.1",
     "@nrwl/jest": "9.5.1",
     "@nrwl/workspace": "9.5.1",
     "@types/crypto-js": "^3.1.47",
     "@types/jest": "25.1.4",
     "@types/node": "~12.12.50",
     "dotenv": "6.2.0",
     "eslint": "6.8.0",
     "jest": "25.2.3",
     "jest-preset-angular": "8.1.2",
     "ng-mocks": "^10.1.1",
     "ng-openapi-gen": "^0.12.1",
     "ts-jest": "25.2.1",
     "ts-node": "~7.0.0",
     "tslint": "~6.0.0",
     "typescript": "~3.8.3"
}
}

tsconfig.json ดูเหมือนว่า:

{
  "compileOnSave": false,
  "compilerOptions": {
    "rootDir": ".",
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "importHelpers": true,
    "target": "es2015",
    "module": "esnext",
    "typeRoots": ["node_modules/@types"],
    "lib": ["es2017", "dom"],
    "skipLibCheck": true,
    "skipDefaultLibCheck": true,
    "baseUrl": ".",
    "paths": {
      // SEVERAL LINES OMITTED FOR CLARITY
    }
  },
  "exclude": ["node_modules", "tmp"]
  "compilerOptions": {
    "types": ["node", "jest"]
  },
  "include": ["**/*.ts"]
}

นี่คือ tsconfig.lib.json

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "../../../dist/out-tsc",
    "target": "es2015",
    "declaration": true,
    "inlineSources": true,
    "types": [],
    "lib": ["dom", "es2018"]
  },
  "angularCompilerOptions": {
    "skipTemplateCodegen": true,
    "strictMetadataEmit": true,
    "enableResourceInlining": true
  },
  "exclude": ["src/test-setup.ts", "**/*.spec.ts"]
}

นี่คือ tsconfig.spec.json

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "../../../dist/out-tsc",
    "module": "commonjs",
    "types": ["jest", "node"]
  },
  "files": ["src/test-setup.ts"],
  "include": ["**/*.spec.ts", "**/*.d.ts"]
}

ฉันได้ค้นหาเว็บและแก้ไขข้อบกพร่องแล้ว แต่ก็ไม่มีประโยชน์ ฉันทำตามที่แนะนำในโพสต์นี้แต่ไม่มีประโยชน์

ในข้อความแสดงข้อผิดพลาดระบุว่าโดยค่าเริ่มต้นหาก Jest เห็นการกำหนดค่า Babel ระบบจะใช้สิ่งนั้นเพื่อแปลงไฟล์ของคุณโดยไม่สนใจ "node_modules"

ฉันไม่รู้ว่าต้องติดตั้ง babeljs ด้วยหรือเปล่า

คำตอบ

1 tmhao2005 Aug 17 2020 at 18:21

เนื่องจากผู้ขายบางเผยแพร่แหล่งที่มาของพวกเขาโดยไม่ต้อง transpiling ดังนั้นคุณจำเป็นต้อง transpile แพคเกจเหล่านี้อีกด้วยbabel-jestในขณะที่ts-jestจะดูแลtsไฟล์ transformIgnorePatternsนอกจากนี้คุณควรเปลี่ยนแพคเกจเหล่านี้อีกครั้งโดยระบุ นี่คือการกำหนดค่า Jest ที่เปลี่ยนไปของคุณ:

const esModules = ['@ckeditor', 'lodash-es'].join('|'); // you can put more if there is others

module.exports = {
  transform: {
    '^.+\\.(ts|html)$': 'ts-jest', '^.+\\.js$': 'babel-jest',
  },
  // ...
  transformIgnorePatterns: [`/node_modules/(?!${esModules})`],
};

เพียงแค่เก็บไว้ในใจ, ติดตั้งbabel, babel-jestและที่ตั้งไว้และสร้างการตั้งค่าสำหรับมัน

// Install
npm i -D @babel/core @babel/preset-env babel-jest 

// babel.config.js
module.exports = function(api) {
  api.cache(true);

  const presets = ['@babel/preset-env'];
  const plugins = [];

  return {
    presets,
    plugins,
  };
};

Biffyn Aug 21 2020 at 23:46

ฉันพบปัญหาเดียวกันเมื่อเปลี่ยนจากlodashเป็นlodash-es. ผมทำในสิ่ง @ tmhao2005 แนะนำและติดตั้ง@babel/core, @babel/preset-envและbabel-jestจากนั้นเพิ่มbabel.config.jsในรากของ Nx Worspace jest.config.tsของฉันและการปรับปรุงฐาน เพื่อให้คุณสามารถลองทำสิ่งต่อไปนี้

ติดตั้งการอ้างอิง

yarn add -D @babel/core @babel/preset-env babel-jest
npm I -D @babel/core @babel/preset-env babel-jest

เพิ่ม babel.config.js

ในรูทของ Nx Workspace ของคุณให้เพิ่ม a babel.config.jsด้วยสิ่งต่อไปนี้ที่นำมาจากเอกสาร Jest

module.exports = {
  presets: [
    [
      '@babel/preset-env',
      {
        targets: {
          node: 'current'
        }
      }
    ]
  ]
};

อัปเดต jest.config.ts

อัปเดต jest.config.ts ฐานในรูทของ Nx Workspace ของคุณให้เป็นแบบนี้ขึ้นอยู่กับความต้องการในการกำหนดค่าของคุณ

module.exports = {
    testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'],
    transform: {
        '^.+\\.(ts|html)$': 'ts-jest', '^.+\\.js$': 'babel-jest'
    },
    resolver: '@nrwl/jest/plugins/resolver',
    moduleFileExtensions: ['ts', 'js', 'html'],
    coverageReporters: ['html', 'json'],
    transformIgnorePatterns: ['/node_modules/(?!lodash-es)']
};

วิธีนี้ใช้ได้ผลสำหรับฉันโดยใช้ NX 10 lodash-esแต่ระยะทางของคุณอาจแตกต่างกันไปตาม@ckeditorแพ็คเกจ คุณจะต้องเพิ่ม@ckeditorแพ็คเกจทั้งหมดที่คุณต้องการลงในไฟล์transformIgnorePatterns

ลิงก์ที่เป็นประโยชน์ที่เป็นไปได้

NX ฉบับ 1091
NX ฉบับ 812