使Angular 8启用jest测试框架

使Angular8能够使用jest

尽管有一些关于如何在Angular 8中使用Jest的文章,但我并不能成功使用它,所以我进行了调查。

无法解析Tc1Component的所有参数: (?). 发生了这个错误。
这实际上是一个在Testbed中,无法解决组件注入并且无法创建实例从而导致失败的问题。

样本项目

Github:Angular8-Jest

构建环境

创建Angular项目

スクリーンショット 2019-11-29 23.12.45.png

为了使这个示例项目更易于使用,我们将删除以下内容:
1. src/
2. e2e/
3. tsconfig.app.json
4. tsconfig.spec.json
5. karma.conf.js

删除 ./e2e/ ./src/ ./tsconfig.app.json ./tsconfig.spec.json karma.conf.js

这里,我们已经从Angular.json中删除了项目信息。但是,ng g application命令至少需要一个项目在Angular.json中注册,才能执行。所以我们先创建一个项目。这次我们想要将其命名为pj1,所以输入ng g application pj1。

我创建了pj1项目,所以要删除angular.json中注册的TestProject。

Angular 8的初始项目已创建完成。

为进行验证,添加组件和服务。

使用ng g component tc1和ng g service ts1进行创建。
此外,为了在引入jest后能够避免出现上述的”无法解析Tc1Component的所有参数: (?)”错误,需要在tc1.component.ts文件中进行以下配置。

import { Component, OnInit } from '@angular/core';
import { Ts1Service } from '../ts1.service';

@Component({
  selector: 'app-tc1',
  templateUrl: './tc1.component.html',
  styleUrls: ['./tc1.component.css']
})
export class Tc1Component implements OnInit {

  constructor(private ts1: Ts1Service) { }

  ngOnInit() {
  }

}

确认可以通过ng test进行正确的测试。

スクリーンショット 2019-11-30 00.05.27.png

将单元测试框架从Jasmine更改为Jest。

删除不必要的库和用于karma的文件。
npm r @types/jasmine @types/jasminewd2 jasmine-core jasmine-spec-reporter karma karma-chrome-launcher karma-coverage-istanbul-reporter karma-jasmine karma-jasmine-html-reporter
rm -f ./projects/pj1/karma.conf.js ./projects/pj1/src/test.ts

安装Jest相关库
npm i -D jest @types/jest @angular-builders/jest

2019/11/30 补充:
确认这些设置只能在7.1.1版本的jest-preset-angular下工作。
请同时执行以下命令:
npm i -D jest-preset-angular@7.1.1

修改Typescript文件。

在tsconfig.json的compilerOptions中添加”esModuleInterop”: true和”emitDecoratorMetadata”: true。

顺便说一下,由于我没有设置”emitDecoratorMetadata”: true,所以出现了无法解析Tc1Component的所有参数的错误。

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "module": "esnext",
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2015",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2018",
      "dom"
    ],
    "esModuleInterop": true,
    "emitDecoratorMetadata": true
  },
  "angularCompilerOptions": {
    "fullTemplateTypeCheck": true,
    "strictInjectionParameters": true
  }
}

tsconfig.app.json和tsconfig.spec.json需要做出以下修改:从exclude中删除 “src/test.ts”。还需要将tsconfig.spec.json中的types从jasmine更改为jest。

{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "outDir": "../../out-tsc/app",
    "types": []
  },
  "files": [
    "src/main.ts",
    "src/polyfills.ts"
  ],
  "include": [
    "src/**/*.ts"
  ],
  "exclude": [
    "src/**/*.spec.ts"
  ]
}
{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "outDir": "../../out-tsc/spec",
    "types": [
      "jest",
      "node"
    ]
  },
  "files": [
    "src/polyfills.ts"
  ],
  "include": [
    "src/**/*.spec.ts",
    "src/**/*.d.ts"
  ]
}

进行jest的设置

创建jest的配置文件

module.exports = {
  globals: {
    'ts-jest': {
      tsConfig: '<rootDir>/projects/pj1/tsconfig.spec.json',
      stringifyContentPathRegex: '\\.html$',
      astTransformers: [
        'jest-preset-angular/InlineHtmlStripStylesTransformer',
      ],
    },
  },
  testMatch: ['**/*.spec.ts'],
  transform: {
    '^.+\\.ts$': 'ts-jest',
  },
  testEnvironment: 'jest-environment-jsdom-thirteen',
  moduleFileExtensions: ['ts', 'html', 'js', 'json'],
  moduleNameMapper: {
    '^src/(.*)$': '<rootDir>/src/$1',
    '^app/(.*)$': '<rootDir>/src/app/$1',
    '^assets/(.*)$': '<rootDir>/src/assets/$1',
    '^environments/(.*)$': '<rootDir>/src/environments/$1',
  },
  transformIgnorePatterns: ['node_modules/.*'],
  snapshotSerializers: [
    'jest-preset-angular/AngularSnapshotSerializer.js',
    'jest-preset-angular/HTMLCommentSerializer.js',
  ],
};

请根据您创建的项目路径适当调整以下内容,只包含带有项目目录信息的部分:
tsConfig: ‘/projects/pj1/tsconfig.spec.json’

设定Angular的设置。

由于目前的情况下无法进行ng test进行单元测试,因此需要在angular.json中进行配置。
※这里只显示了必要的部分,请只修改相关部分。

以下的数据将用于ng test时的配置。

{
  "projects": {
    "pj1": {
      "architect": {
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "projects/pj1/src/test.ts",
            "polyfills": "projects/pj1/src/polyfills.ts",
            "tsConfig": "projects/pj1/tsconfig.spec.json",
            "karmaConfig": "projects/pj1/karma.conf.js",
            "assets": [
              "projects/pj1/src/favicon.ico",
              "projects/pj1/src/assets"
            ],
            "styles": [
              "projects/pj1/src/styles.scss"
            ],
            "scripts": []
          }
        }
      }
    }
  }
}

请按以下方式进行修改。

{
  "projects": {
    "pj1": {
      "architect": {
        "test": {
          "builder": "@angular-builders/jest:run"
        }
      }
    }
  }
}

我试着运行了ng test来进行单元测试。

首先,让我们确认实际测试是否运行正常。
如果有以下五个测试通过,就表示成功了。

スクリーンショット 2019-11-30 00.09.33.png

给一个额外的东西

让我们试着引发一个“无法解析Tc1Component的所有参数:(?)” 的错误。
请从tsconfig.json中删除”emitDecoratorMetadata”: true的设置,并尝试运行ng test。

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "module": "esnext",
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2015",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2018",
      "dom"
    ],
    "esModuleInterop": true
  },
  "angularCompilerOptions": {
    "fullTemplateTypeCheck": true,
    "strictInjectionParameters": true
  }
}
スクリーンショット 2019-11-30 00.13.54.png

最后

在我注意到tsconfig的设置不正确之前,我花了两个小时的时间。我希望通过这篇文章,能够尽量减少大家的时间。

那么,祝您有一个愉快的生活。

广告
将在 10 秒后关闭
bannerAds