我试图用以下代码测试ngModel的双向数据绑定,但是当我运行我的测试时我总是得到: Expected '' to be 'test@wikitude.com', 'searchQuery property changes after text input'. 也许它与 searchField.dispatchEvent 部分有关,但到目前为止我无法弄清楚为什么测试没有改变我的 displayField 的textContent . 该项目是用 angular-cli": "1.0.0-beta.15 建造的 . 我试图按照这个guide但到目前为止没有运气 . 如果你能帮助我完成测试通过会很好 . 我不确定是否必须使用 fixture.whenStable() - 正如我在another question的答案中看到的那样 - 但我不认为在输入字段中输入文本是异步活动 - 我还实现了在提到的 sendInput() 方法这个问题,但到目前为止还没有任何成功 .

这是我的组成部分:

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

@Component({
  selector: 'app-search',
  templateUrl: './search.component.html',
  styleUrls: ['./search.component.css']
})
export class SearchComponent implements OnInit {
  searchQuery: string;
  active: boolean = false;

  onSubmit(): void {
    this.active = true;
  }
}

这是我的组件模板:

<input id="name" [(ngModel)]="searchQuery" placeholder="customer">
<h2><span>{{searchQuery}}</span></h2>

以下是我的规格:

/* tslint:disable:no-unused-variable */

import {TestBed, async, ComponentFixture, tick} from '@angular/core/testing';
import { SearchComponent } from './search.component';
import {CommonModule} from "@angular/common";
import {FormsModule} from "@angular/forms";
import {By} from "@angular/platform-browser";

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

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

    fixture = TestBed.createComponent(SearchComponent);
    component = fixture.componentInstance;
  });

  it('should bind the search input to the searchQuery variable', () => {   
    const searchInputText: string = 'test@wikitude.com';
    const searchField: HTMLInputElement = fixture.debugElement.query(By.css('input')).nativeElement;
    const displayField: HTMLElement = fixture.debugElement.query(By.css('span')).nativeElement;

    searchField.value = searchInputText;

    searchField.dispatchEvent(new Event('input'));

    fixture.detectChanges();

    expect(displayField.textContent).toBe(searchInputText, 'searchQuery property changes after text input');
  });
});

Update: 我将测试更改为以下内容,使其通过 - 只要输入字段不在表单标记内:

/* tslint:disable:no-unused-variable */

import {TestBed, async, ComponentFixture, tick} from '@angular/core/testing';
import { SearchComponent } from './search.component';
import {CommonModule} from "@angular/common";
import {FormsModule} from "@angular/forms";
import {By} from "@angular/platform-browser";

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

  function sendInput(text: string, inputElement: HTMLInputElement) {
    inputElement.value = text;
    inputElement.dispatchEvent(new Event('input'));
    fixture.detectChanges();
    return fixture.whenStable();
  }

  beforeEach(done => {
      declarations: [SearchComponent],
      imports: [
        CommonModule,
        FormsModule
      ]
    });

    TestBed.compileComponents().then(() => {
      fixture = TestBed.createComponent(SearchComponent);
      component = fixture.componentInstance;
      fixture.detectChanges();
      done();
    })
  });

  it('should bind the search input to the searchQuery variable', done => {
    const searchInputText: string = 'test@wikitude.com';
    const searchField: HTMLInputElement = fixture.debugElement.query(By.css('#name')).nativeElement;

    sendInput(searchInputText, searchField).then(() => {
      expect(component.searchQuery).toBe(searchInputText);
      done();
    });
  });
});

这是更新的模板:

<form>
  <input id="name" [(ngModel)]="searchQuery" placeholder="customer" name="name" #name="ngModel">
</form>
<h2><span>{{searchQuery}}</span></h2>

我得到的测试结果是: Expected undefined to be 'test@wikitude.com'.