如何测试Angular 2 双向绑定输入值

How to test Angular 2 two way binding input value

我正在尝试为我的组件编写测试以测试angular双向绑定是否正常工作。

一方面,我有一个看起来像这样的测试(并且通过了):

it('should bind displayed value to the SearchComponent property', () => {
    searchComponent.searchBoxValue = 'abc';
    searchCompFixture.detectChanges();
    expect(inputEl.nativeElement.getAttribute('ng-reflect-model')).toBe('abc');
});

其中

searchCompFixture = TestBed.createComponent(SearchComponent);
inputEl = searchCompFixture.debugElement.query(By.css('#search-box-input'));

<input
    id="search-box-input"
    [(ngModel)]="searchBoxValue"\>

另一方面,我想编写一个测试,首先设置输入元素的值并检查 SearchComponent 属性 值是否已更改。我的尝试:

it('should bind SearchComponent property to the displayed value', fakeAsync(() => {
    inputEl.nativeElement.value = 'abc';
    let evt = new Event('input');
    inputEl.nativeElement.dispatchEvent(evt);

    tick();

    searchCompFixture.detectChanges();
    expect(searchComponent.searchBoxValue).toBe('abc');
}));

但这不起作用,因为 searchComponent.searchBoxValue 值未设置。有什么解决办法吗?

事实证明,您需要 detechtChanges 才能更新输入字段的值(我知道为什么)。这是工作测试:

it('should bind SearchComponent property to the displayed value', fakeAsync(() => {
    searchCompFixture.detectChanges();

    inputEl.nativeElement.value = 'abc';
    let event = new Event('input');
    inputEl.nativeElement.dispatchEvent(event);

    tick();
    expect(searchCompFixture.componentInstance.searchBoxValue).toEqual('abc');
}));

编辑: 我发现了测试的另一个改进 should bind displayed value to the SearchComponent property。我不喜欢的是我使用了奇怪的 angular 属性 ng-reflect-model 而不是正常的方式 inputEl.nativeElement.value。问题是 value 还没有被 angular 设置。

将测试更改为以下内容即可解决问题,不再需要任何魔法 - 太棒了!

it('should bind displayed value to the SearchComponent property', fakeAsync(() => {
    searchComponent.searchBoxValue = 'abc';

    searchCompFixture.detectChanges();
    tick();
    searchCompFixture.detectChanges();


    expect(inputEl.nativeElement.value).toBe('abc');
}));