Angular 2 测试输入框绑定

Angular 2 Testing Input Box Binding

我似乎无法测试绑定到 Angluar2 模型的输入框。我对此有点陌生,所以请耐心等待。

我有一个非常基本的 Angular2 组件,其中包含一个绑定到模型的输入框。

<form>
    <input  type="text" [(ngModel)]="searchTerm" name="termsearchTerm" (keyup)="search()"  value=""/>
</form>

下面是代码:

import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
    moduleId: module.id,
    selector: 'sc-search',
    templateUrl: 'search.component.html'
})

export class SearchComponent {
    @Input() data: any;
    @Output() onSearchTermChanged = new EventEmitter<string>();
    private searchTerm: string;

    search() {
        this.onSearchTermChanged.emit(this.searchTerm);
    }
}

当 运行 下面的测试不断得到 Expected undefined to equal 'John'。 我期待测试通过。

 searchableHierarchyComponentFixture.detectChanges();

    let termInputDbg = searchableHierarchyComponentFixture.debugElement.query(By.css('input[name="termsearchTerm"]'));
    let input = searchableHierarchyComponentFixture.nativeElement.querySelector('input');

    input.value = 'John';

    let evt = document.createEvent('Event');
    evt.initEvent('keyup', true, false);

    termInputDbg.triggerEventHandler('keyup', null);
    input.dispatchEvent(evt);


    tick(50);
    searchableHierarchyComponentFixture.detectChanges();
    searchableHierarchyComponentFixture.whenStable();
    expect(searchableHierarchyComponentFixture.componentInstance.searchTerm).toEqual('John');

所以有几件事:

  1. 创建组件后需要调用tick。不完全确定,但我认为模型绑定是异步发生的。不勾选,测试将失败。
  2. 该指令侦听 input 事件,而不是 keyup。当 input 事件发生时,指令更新绑定。

这是一个完整的测试(也在 Plunker 上)

import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { TestBed, fakeAsync, tick } from '@angular/core/testing';
import { By } from '@angular/platform-browser';

@Component({
  selector: 'test',
  template: `
    <form>
      <input type="text" [(ngModel)]="query" name="query" />
    </form>
  `
})
class TestComponent {
  query: string;
}

describe('TestComponent: ngModel', () => {

  let fixture;
  let component;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [FormsModule],
      declarations: [TestComponent]
    });
    fixture = TestBed.createComponent(TestComponent);
    component = fixture.componentInstance;
  });

  it('should change the value', fakeAsync(() => {
    let input = fixture.debugElement.query(By.css('input')).nativeElement;

    fixture.detectChanges();
    tick();

    expect(component.query).toBeFalsy();

    input.value = 'Hello World';
    input.dispatchEvent(new Event('input'));
    tick();

    expect(component.query).toBe('Hello World');

  }));
});

另见