如何在Angular2中正确使用detectChanges()方法?

3

我在Jasmine中有以下代码:

    it('should pass on writing secondvalue in the input', async(() => {

      const fixture=TestBed.createComponent(AppComponent);
      const app=fixture.debugElement.nativeElement.querySelector("input").getAttribute("value");
      expect(app).toContain("firstvalue");
      fixture.detectChanges();
      expect(app).toContain("secondvalue");

      }));

问题在于,一旦我运行测试,测试就会失败。我期望它等待detectChanges(),但它没有。
如何正确实现:等待第二个值输入到输入框中,并检查该值是否为"secondvalue"。
fixture.detectChanges()难道不应该像一个阻塞器一样工作吗?例如,当有人开始在输入框中输入时,它应该等待输入被触发吧?
1个回答

3

当您更改组件状态时,运行 detectChanges 以使更改传播。

例如:

pageTitle: string;
ngOnInit() {
    this.pageTitle = 'first title';
}

在模板中:

<h4>{{pageTitle}}</h4>

在测试中:

const fixture = TestBed.createComponent(AppComponent);
const h4 = fixture.debugElement.query(By.css('h4'));

console.log(component.pageTitle); // 'first title'
console.log(h4.nativeElement.textContent); // ''
fixture.detectChanges(); // Propagates ngOnInit changes
console.log(h4.nativeElement.textContent); // 'first title'

component.pageTitle = 'second title'; // Here we change state
console.log(component.pageTitle); // 'second title'
console.log(h4.nativeElement.textContent); // 'first title'
fixture.detectChanges(); // Propagate changes
console.log(h4.nativeElement.textContent); // 'second title'

一个典型的用例是检查依赖于状态的事物,例如在模板中有以下内容:
<div id="xxx" *ngIf="over18">Restricted content</div>

在组件中:
over18: boolean = false;

在测试中:

it('should show restricted content if over 18', () => {
    component.over18 = true; // change state from the default one
    fixture.detectChanges(); // propagate changes to view

    // now we can actually test
    const divElem = fixture.debugElement.query(By.css('div#xxx')); // would be null if not shown in DOM
    expect(divElem).toBeTruthy();
});

请注意,我正在测试组件逻辑。在我的看法中,检查如果我在输入框中输入“asdf”它的值是否会更新不属于单元测试范围-这个功能由HTML标准/Angular团队提供。


你的意思是我必须明确地放入新值,对吗?它可以放在 karma runner 的输入中吗? - masterach
@masterach 你很可能需要在测试值之前调用 fixture.detectChanges()。此外,不太清楚你的组件是什么样子的,以及其中的值如何更改。 - Marian
const h4 = fixture.debugElement.query(By.css('h4')); 不应该改为 const h2 = fixture.debugElement.query(By.css('h2')); 吗? - Anders Persson
@AndersPersson 应该可以,不过希望示例本身已经足够清晰了。谢谢您的注意,我已经更新了答案。您也可以提交自己的编辑并等待人们批准您的建议更改,而不是留下评论。 - Marian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接