首页 > 解决方案 > 如何在 Angular 模板驱动的表单中对验证消息进行单元测试

问题描述

我有一个非常基本的 Angular 模板驱动表单,其中包含一个必需的字段。如果该字段无效,则会显示一条验证消息,这是首次加载组件时的情况,因为该字段是必需的但为空。在应用程序中查看时,代码按预期运行并显示验证消息。

当通过 Jasmine 单元测试测试组件时,不会收到验证消息并且测试失败。

我相信查找验证消息的逻辑是有效的,因为如果我删除消息 DIV 上的 *ngIf 指令,则测试通过。

我尝试了以下方法:

模板:

<form #form="ngForm">

  <label>First name:</label>

  <input #firstName="ngModel"
    type="text"
    name="firstName"
    [(ngModel)]="firstNameText"
    required />

  <div class="validation-error" *ngIf="firstName.invalid">
      Please enter a valid first name
  </div>
</form>

组件类:

import { Component } from '@angular/core';

@Component({
  selector: 'app-person-form',
  templateUrl: './person-form.component.html'
})
export class PersonFormComponent  {
  public firstNameText: string;
}

茉莉花测试规格:

import { ComponentFixture, TestBed, fakeAsync } from '@angular/core/testing';
import { PersonFormComponent } from './person-form.component';
import { FormsModule } from '@angular/forms';
import { DebugElement } from '@angular/core';
import { By } from '@angular/platform-browser';

describe('PersonFormComponent', () => {
  let fixture: ComponentFixture<PersonFormComponent>;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [ FormsModule ],
      declarations: [ PersonFormComponent ]
    });

    fixture = TestBed.createComponent(PersonFormComponent);
    fixture.detectChanges();
  });

  it('should show a validation error if the first name was touched but left empty', () => {
    let firstNameValidationError: DebugElement;

    // try to get a handle to the validation message (should exist as form is invalid):
    firstNameValidationError = fixture.debugElement.query(By.css('.validation-error'));

    // the validation error should be found:
    expect(firstNameValidationError).toBeTruthy();
  });
});

标签: angularunit-testingjasmineangular-forms

解决方案


组件初始化应始终在一个async块中完成

beforeEach(async() => {
    TestBed.configureTestingModule({
      imports: [ FormsModule ],
      declarations: [ PersonFormComponent ]
    });

    fixture = TestBed.createComponent(PersonFormComponent);
    fixture.detectChanges();
});

此外,您可能需要在组件初始化后再次运行更改检测

it('should show a validation error if the first name was touched but left empty', () => {
    let firstNameValidationError: DebugElement;

    fixture.detectChanges(); // run change detection
    firstNameValidationError = fixture.debugElement.query(By.css('.validation-error'));

    // the validation error should be found:
    expect(firstNameValidationError).toBeTruthy();
});

推荐阅读