使Angular 8启用jest测试框架
使Angular8能够使用jest
尽管有一些关于如何在Angular 8中使用Jest的文章,但我并不能成功使用它,所以我进行了调查。
无法解析Tc1Component的所有参数: (?). 发生了这个错误。
这实际上是一个在Testbed中,无法解决组件注入并且无法创建实例从而导致失败的问题。
样本项目
Github:Angular8-Jest
构建环境
创建Angular项目

为了使这个示例项目更易于使用,我们将删除以下内容:
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进行正确的测试。

将单元测试框架从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来进行单元测试。
首先,让我们确认实际测试是否运行正常。
如果有以下五个测试通过,就表示成功了。

给一个额外的东西
让我们试着引发一个“无法解析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
}
}

最后
在我注意到tsconfig的设置不正确之前,我花了两个小时的时间。我希望通过这篇文章,能够尽量减少大家的时间。
那么,祝您有一个愉快的生活。