Events 角度2:测试[(ngModel)]双向数据绑定

Events 角度2:测试[(ngModel)]双向数据绑定,events,testing,angular,jasmine,Events,Testing,Angular,Jasmine,我试图用以下代码测试ngModel的双向数据绑定,但当我运行测试时,我总是得到:Expected''to'test@wikitude.com“,”文本输入后searchQuery属性发生更改。“可能与searchField.dispatchEvent部分有关,但到目前为止,我还不明白为什么测试没有改变我的displayField的文本内容。该项目是使用angular cli:“1.0.0-beta.15构建的。我试着跟着这个,但到目前为止没有运气。如果你能帮我通过考试就好了。我不确定是否必须使用

我试图用以下代码测试ngModel的双向数据绑定,但当我运行测试时,我总是得到:
Expected''to'test@wikitude.com“,”文本输入后searchQuery属性发生更改。“
可能与
searchField.dispatchEvent
部分有关,但到目前为止,我还不明白为什么测试没有改变我的
displayField
的文本内容。该项目是使用
angular cli:“1.0.0-beta.15
构建的。我试着跟着这个,但到目前为止没有运气。如果你能帮我通过考试就好了。我不确定是否必须使用fixture.whenStable()——正如我在回答中看到的那样——但我不认为在输入字段中键入文本是一种异步活动——我还实现了这个问题中提到的
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>
<form>
  <input id="name" [(ngModel)]="searchQuery" placeholder="customer" name="name" #name="ngModel">
</form>
<h2><span>{{searchQuery}}</span></h2>

{{searchQuery}}
以下是我的规格:

/* 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');
  });
});
/*tslint:disable:没有未使用的变量*/
从“@angular/core/testing”导入{TestBed,async,ComponentFixture,tick};
从“./search.component”导入{SearchComponent};
从“@angular/common”导入{CommonModule}”;
从“@angular/forms”导入{FormsModule};
从“@angular/platform browser”导入{By}”;
描述('组件:搜索组件',()=>{
let组件:SearchComponent;
let夹具:组件夹具;
在每个之前(()=>{
TestBed.configureTestingModule({
声明:[SearchComponent],
进口:[
公共模块,
FormsModule
]
});
fixture=TestBed.createComponent(SearchComponent);
组件=fixture.componentInstance;
});
它('应该将搜索输入绑定到searchQuery变量',()=>{
const searchInputText:string='1〕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;
dispatchEvent(新事件('input'));
fixture.detectChanges();
expect(displayField.textContent).toBe(searchInputText,“文本输入后searchQuery属性更改”);
});
});
更新: 我将测试更改为以下内容,从而使其通过-只要输入字段不在表单标记内:

/* 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();
    });
  });
});
/*tslint:disable:没有未使用的变量*/
从“@angular/core/testing”导入{TestBed,async,ComponentFixture,tick};
从“./search.component”导入{SearchComponent};
从“@angular/common”导入{CommonModule}”;
从“@angular/forms”导入{FormsModule};
从“@angular/platform browser”导入{By}”;
描述('组件:搜索组件',()=>{
let组件:SearchComponent;
let夹具:组件夹具;
函数sendInput(文本:字符串,inputElement:HTMLInputElement){
inputElement.value=文本;
dispatchEvent(新事件('input'));
fixture.detectChanges();
返回夹具。whenStable();
}
每次之前(完成=>{
声明:[SearchComponent],
进口:[
公共模块,
FormsModule
]
});
TestBed.compileComponents()。然后(()=>{
fixture=TestBed.createComponent(SearchComponent);
组件=fixture.componentInstance;
fixture.detectChanges();
完成();
})
});
它('应将搜索输入绑定到searchQuery变量',完成=>{
const searchInputText:string='1〕test@wikitude.com';
const searchField:HTMLInputElement=fixture.debugElement.query(By.css('#name')).nativeElement;
sendInput(searchInputText,searchField)。然后(()=>{
expect(component.searchQuery).toBe(searchInputText);
完成();
});
});
});
以下是更新的模板:

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

{{searchQuery}}

我得到的测试结果是:
预期未定义为'test@wikitude.com“。

您应该
TestBed.compileComponents()。然后(…)
以确保组件已正确初始化。您可能还需要更多的等待(解析
.whenStable
)才能正确更新组件。例如,请参阅@jornsharpe:Thank的可能重复项,这已奏效-但现在,当我将输入放入表单标记中时,它似乎不再奏效<代码>请给出一个答案,“似乎不起作用”是什么意思?也许接受副本,再写一个问题?