Angular 8 - 加载垫模块的单元测试问题
Posted
技术标签:
【中文标题】Angular 8 - 加载垫模块的单元测试问题【英文标题】:Angular 8 - Unit Test issue with loading mat-modules 【发布时间】:2021-01-01 07:56:42 【问题描述】:我正在尝试为登录组件编写 Angular 的单元测试。 在组件中,我使用 mat-form-field、mat-label、mat-icon 和 mat-error。 他们工作正常。但是当我运行 ng test --code-coverage
所有模块都导入/导出到一个名为 material-module 的模块。然后我将该模块导入登录模块。 这是我的 login.component.html
<div class="text-center">
<h1>S'identifier</h1>
</div>
<form class="" [formGroup]="userForm" (ngSubmit)="submit(userForm)">
<div class="card-body p-6 mb-3">
<div class="form-group">
<mat-form-field appearance="outline" class="login-id-form-field">
<mat-label>Identifiant</mat-label>
<input
matInput
id="email"
type="email"
class="login-id"
[formControl]="userForm.controls['email']"
[errorStateMatcher]="matcher"
/>
<mat-icon
matSuffix
class="red-icon error-icon"
*ngIf="
matcher.isErrorState(userForm.controls['email']) &&
userForm.controls['email'].errors
"
>error</mat-icon
>
<mat-icon
matSuffix
class="green-icon error-icon"
*ngIf="!userForm.controls['email'].errors"
>
check_circle
</mat-icon>
<mat-error *ngIf="userForm.controls['email'].errors">
Identifiant invalide
</mat-error>
</mat-form-field>
</div>
<div class="form-group">
<mat-form-field
appearance="outline"
class="login-id-form-field password-form-field"
>
<mat-label>Mot de passe</mat-label>
<input
matInput
id="password"
type="password"
class="login-id"
[formControl]="userForm.controls['password']"
[errorStateMatcher]="matcher"
/>
<mat-icon
matSuffix
class="red-icon error-icon"
*ngIf="
matcher.isErrorState(userForm.controls['password']) &&
userForm.controls['password'].errors
"
>
error
</mat-icon>
<mat-icon
matSuffix
class="green-icon error-icon"
*ngIf="!userForm.controls['password'].errors"
>
check_circle
</mat-icon>
<mat-error *ngIf="userForm.controls['password'].errors">
Mot de passe invalide ( passwordStrength.label )
</mat-error>
</mat-form-field>
<div class="d-flex mt-2" style="height: 24px">
<mat-error *ngIf="auth.loginError.length && userForm.valid">
E-mail ou mot de passe incorrect
</mat-error>
<div class="ml-auto text-right">
<a [routerLink]="'reset-password'">Mot de passe oublié ?</a>
</div>
</div>
</div>
<div class="form-footer mt-5">
<button
type="submit"
class="btn d-block mx-auto primary-strada-btn strada-btn-large"
[disabled]="!userForm.valid || auth.loggingIn"
>
Connexion
</button>
</div>
</div>
</form>
这是我的login.component.spec.ts
import TestBed, ComponentFixture from "@angular/core/testing";
import ReactiveFormsModule, FormsModule from "@angular/forms";
import LoginPageComponent from "./login-page.component";
// import LoginPageComponent, User from "./login-page.component";
describe("Component: Login", () =>
let component: LoginPageComponent;
let fixture: ComponentFixture<LoginPageComponent>;
beforeEach(() =>
// refine the test module by declaring the test component
TestBed.configureTestingModule(
imports: [ReactiveFormsModule, FormsModule],
declarations: [LoginPageComponent],
);
// create component and test fixture
fixture = TestBed.createComponent(LoginPageComponent);
// get test component from the fixture
component = fixture.componentInstance;
component.ngOnInit();
);
it("form invalid when empty", () =>
expect(component.userForm.valid).toBeFalsy();
);
);
我收到这些错误。
Your global Angular CLI version (10.0.5) is greater than your local
version (8.0.6). The local Angular CLI version is used.
To disable this warning use "ng config -g cli.warnings.versionMismatch false".
14 09 2020 15:01:47.510:INFO [framework:karma-parallel]: sharding specs across 4 browsers
10% building 2/2 modules 0 active14 09 2020 15:01:53.934:INFO [karma-server]: Karma v4.1.0 server started at http://0.0.0.0:9876/
14 09 2020 15:01:53.936:INFO [launcher]: Launching browsers ChromeHeadless, ChromeHeadless, ChromeHeadless, ChromeHeadless with concurrency unlimited
14 09 2020 15:01:53.943:INFO [launcher]: Starting browser ChromeHeadless
14 09 2020 15:01:53.950:INFO [launcher]: Starting browser ChromeHeadless
14 09 2020 15:01:53.954:INFO [launcher]: Starting browser ChromeHeadless
14 09 2020 15:01:53.964:INFO [launcher]: Starting browser ChromeHeadless
14 09 2020 15:02:10.647:INFO [HeadlessChrome 85.0.4183 (Windows 10.0.0)]: Connected on socket ASC5nD0AuFD0GspSAAAA with id 52943636
14 09 2020 15:02:10.652:INFO [HeadlessChrome 85.0.4183 (Windows 10.0.0)]: Connected on socket QA4STEUC5v4EV55_AAAB with id 27694527
14 09 2020 15:02:10.655:INFO [HeadlessChrome 85.0.4183 (Windows 10.0.0)]: Connected on socket 060bO_di1o_9LmmsAAAC with id 63183944
14 09 2020 15:02:10.658:INFO [HeadlessChrome 85.0.4183 (Windows 10.0.0)]: Connected on socket iAPjmFOsygupfAcZAAAD with id 2553141
HeadlessChrome 85.0.4183 (Windows 10.0.0): Executed 0 of 1 SUCCESS (0 secs / 0 secs)
WARN: 'Spec '[karma-parallel] Add single test to prevent failure should prevent on this shard failing by having successful tests' has no expectations.'
HeadlessChrome 85.0.4183 (Windows 10.0.0): Executed 0 of 1 SUCCESS (0 secs / 0 secs)
WARN: 'Spec '[karma-parallel] Add single test to prevent failure should prevent on this shard failing by having successfHeadlessChrome 85.0.4183 (Windows 10.0.0): Executed 1 of 1 SUCCESS (0.032 secs / 0.004 secs)
HeadlessChrome 85.0.4183 (Windows 10.0.0): Executed 1 of 1 SUCCESS (0.032 secs / 0.004 secs)
HeadlessChrome 85.0.4183 (Windows 10.0.0): Executed 1 of 1 SUCCESS (0.032 secs / 0.004 secs)
HeadlessChrome 85.0.4183 (Windows 10.0.0) WARN: 'Spec '[karma-parallel] Add single test to prevent failure should prevent on this shard failing by having successful tests' has no expectations.'
HeadlessChrome 85.0.4183 (Windows 10.0.0): Executed 1 of 1 SUCCESS (0.032 secs / 0.004 secs)
HeadlessChrome 85.0.4183 (Windows 10.0.0): Executed 0 of 1 SUCCESS (0 secs / 0 secs)
HeadlessChrome 85.0.4183 (Windows 10.0.0) Component: Login form invalid when empty FAILED
1. If 'mat-label' is an Angular component, then verify that it is part of this module.
2. If 'mat-label' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. ("class="form-group">
<mat-form-field appearance="outline" class="login-id-form-field">
[ERROR ->]<mat-label>Identifiant</mat-label>
<input
matInput
class="login-id"
[formControl]="userForm.controls['email']"
[ERROR ->][errorStateMatcher]="matcher"
/>
<mat-icon
1. If 'mat-icon' is an Angular component, then verify that it is part of this module.
error properties: Object( ngSyntaxError: true, ngParseErrors: [ 'mat-label' is not a known element:
"): ng:///DynamicTestModule/LoginPageComponent.html@7:8, Can't bind to 'errorStateMatcher' since it isn't a known property of 'input'. ("
"): ng:///DynamicTestModule/LoginPageComponent.html@14:10, 'mat-icon' is not a known element:
2. If 'mat-icon' is a Web ...
at <Jasmine>
at syntaxError (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:2175:1)
at TemplateParser.parse (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:11169:1)
at JitCompiler._parseTemplate (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:25541:1)
at JitCompiler._compileTemplate (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:25529:61)
at http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:25473:1
at <Jasmine>
at JitCompiler._compileComponents (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:25473:1)
at http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:25393:1
at Object.then (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:2166:27)
at JitCompiler._compileModuleAndAllComponents (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:25391:1)
TypeError: Cannot read property 'userForm' of undefined
at <Jasmine>
at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/webpack:/src/app/login/login-page/login-page.component.spec.ts:26:22)
at ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-evergreen.js:359:1)
at ProxyZoneSpec.push../node_modules/zone.js/dist/zone-testing.js.ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:308:1)
at ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-evergreen.js:358:1)
at Zone.run (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-evergreen.js:124:1)
at runInTestZone (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:561:1)
at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:576:1)
at <Jasmine>
HeadlessChrome 85.0.4183 (Windows 10.0.0): Executed 1 of 1 SUCCESS (0.032 secs / 0.004 secs)
HeadlessChrome 85.0.4183 (Windows 10.0.0): Executed 1 of 1 (1 FAILED) (0 secs / 0.255 secs)
HeadlessChrome 85.0.4183 (Windows 10.0.0): Executed 2 of 5 SUCCESS (0 secs / 0.159 secs)
HeadlessChrome 85.0.4183 (Windows 10.0.0): Executed 1 of 1 SUCCESS (0.026 secs / 0.004 secs)
HeadlessChrome 85.0.4183 (Windows 10.0.0) Component: Login form invalid when empty FAILED
1. If 'mat-label' is an Angular component, then verify that it is part of this module.
2. If 'mat-label' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. ("class="form-group">
<mat-form-field appearance="outline" class="login-id-form-field">
[ERROR ->]<mat-label>Identifiant</mat-label>
<input
matInput
class="login-id"
[formControl]="userForm.controls['email']"
[ERROR ->][errorStateMatcher]="matcher"
/>
<mat-icon
1. If 'mat-icon' is an Angular component, then verify that it is part of this module.
error properties: Object( ngSyntaxError: true, ngParseErrors: [ 'mat-label' is not a known element:
"): ng:///DynamicTestModule/LoginPageComponent.html@7:8, Can't bind to 'errorStateMatcher' since it isn't a known property of 'input'. ("
"): ng:///DynamicTestModule/LoginPageComponent.html@14:10, 'mat-icon' is not a known element:
2. If 'mat-icon' is a Web ...
at <Jasmine>
at syntaxError (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:2175:1)
at TemplateParser.parse (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:11169:1)
at JitCompiler._parseTemplate (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:25541:1)
at JitCompiler._compileTemplate (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:25529:61)
at http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:25473:1
at <Jasmine>
at JitCompiler._compileComponents (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:25473:1)
at http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:25393:1
at Object.then (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:2166:27)
at JitCompiler._compileModuleAndAllComponents (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:25391:1)
TypeError: Cannot read property 'userForm' of undefined
at <Jasmine>
at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/webpack:/src/app/login/login-page/login-page.component.spec.ts:26:22)
at ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-evergreen.js:359:1)
at ProxyZoneSpec.push../node_modules/zone.js/dist/zone-testing.js.ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:308:1)
at ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-evergreen.js:358:1)
at Zone.run (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-evergreen.js:124:1)
at runInTestZone (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:5HeadlessChrome 85.0.4183 (Windows 10.0.0): Executed 1 of 1 SUCCESS (0.032 secs / 0.004 secs)
HeadlessChrome 85.0.4183 (Windows 10.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.307 secs / 0.255 secs)
HeadlessChrome 85.0.4183 (Windows 10.0.0): Executed 5 of 5 SUCCESS (0.3 secs / 0.248 secs)
HeadlessChrome 85.0.4183 (Windows 10.0.0): Executed 1 of 1 SUCCESS (0.026 secs / 0.004 secs)
=============================== Coverage summary ===============================
Statements : 23.48% ( 31/132 )
Branches : 2.44% ( 1/41 )
Functions : 10.42% ( 5/48 )
Lines : 21.14% ( 26/123 )
================================================================================
【问题讨论】:
如果您不打算测试我们通常不做的html,您可以添加TestBed.configureTestingModule(...).overrideTemplate(LoginPageComponent, '');
【参考方案1】:
我只需要导入 AngularMaterialModule
// refine the test module by declaring the test component
TestBed.configureTestingModule(
imports: [
ReactiveFormsModule,
FormsModule,
AngularMaterialModule], <-------------------------------------------
declarations: [LoginPageComponent],
);```
【讨论】:
以上是关于Angular 8 - 加载垫模块的单元测试问题的主要内容,如果未能解决你的问题,请参考以下文章
Angular:单元测试路由:预期 '' 是 '/route'
将 Swiper 6 升级到 7 后,在单元测试(开玩笑)上找不到模块“swiper_angular”
Angular 2 单元测试 - 出现错误无法加载“ng:///DynamicTestModule/module.ngfactory.js”