如何以Angular模板驱动的形式对测试验证消息进行单元化

时间:2019-02-05 15:16:44

标签: angular unit-testing jasmine angular-forms

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

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

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

我尝试了以下方法:

  • 将BrowserModule导入测试规范
  • 在fakeAsync()块中运行测试

模板:

<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();
  });
});

3 个答案:

答案 0 :(得分:1)

完整的修订测试如下,这要感谢Amit Chigadani解决了这个问题:

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(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

    // 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();
  });
});

答案 1 :(得分:0)

在测试开始时添加这些行

 let component = fixture.componentInstance;
    component.firstNameText = '';
    fixture.detectChanges();

然后在此之后,为firstNameText设置一些名称,如下所示:

component.firstNameText = 'test';

这时,您应该期望该错误是虚假的。

答案 2 :(得分:0)

组件初始化应始终在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();
});