我有一个带文本输入的简单Angular组件,它使用ngModel绑定 . 组件工作正常,但不是单元测试 .

helloworld.component.html:

<div>
  <input [(ngModel)]="name" >
  <p>{{msg}} {{name}}</p>
</div>

helloworld.component.ts:

import { Component, OnInit, Input } from '@angular/core';
@Component({
  selector: 'hello-world',
  templateUrl: './helloworld.component.html',
  styleUrls: ['./helloworld.component.css']
})
export class HelloWorldComponent {
  @Input() name: string = "World";
  @Input() msg: string = "Hello";
}

helloworld.component.spec.ts:

import { async, ComponentFixture, TestBed, fakeAsync, tick } from 
'@angular/core/testing';
import { CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA } from '@angular/core';
import { HelloWorldComponent } from './helloworld.component';

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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ HelloWorldComponent ],
      schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(HelloWorldComponent);
    component = fixture.componentInstance;
  });

  it('should print the name on input', ()=>{
    component.msg = "Hi";
    fixture.detectChanges();

    var nameInput: HTMLInputElement = fixture.nativeElement.querySelector('input');
    var label: HTMLElement = fixture.nativeElement.querySelector('p');

    nameInput.value = 'John';
    nameInput.dispatchEvent(new Event('input'));
    fixture.detectChanges();
    expect(component.msg).toBe('Hi');
    expect(component.name).toBe('John');
    expect(label.textContent).toBe('Hi John');
  });
});

测试失败,因为name未设置为'John'但仍具有默认值'World' . 提供的代码在我看来相当于Angular文档中的示例(https://angular.io/guide/testing#component-binding

有些文章解释了在async()中执行测试,并在更改输入值后使用fixture.whenStable() . then() .

我还发现了在fakeAsync()中运行测试的提示,并使用tick()等待输入值绑定到name . 两者都没有帮助 .

我错过了什么?