【发布时间】:2018-03-04 21:21:38
【问题描述】:
如何使单元测试中的变更检测正常工作? 从源代码来看,应该在微任务为空(包括事件任务?)后运行 changeDetection。
this._onMicrotaskEmptySubscription = ngZone.onMicrotaskEmpty.subscribe({
next: () => {
if (this._autoDetect) {
// Do a change detection run with checkNoChanges set to true to check
// there are no changes on the second run.
this.detectChanges(true);
}
}
});
在这个简短的示例中,更改检测在 setTimeout 之后运行,但不是在手动单击元素之后运行。是否有适当的方法在事件调度后触发更改检测(在 fakeAsync 区域内,没有 fixture.detectChanges,因为在这种情况下更改检测与现实生活中的不同)?
import {
fakeAsync, tick, ComponentFixture, TestBed, ComponentFixtureAutoDetect
} from '@angular/core/testing';
import {
Component, QueryList, ViewChildren
} from '@angular/core';
import { By } from '@angular/platform-browser';
import { CommonModule } from '@angular/common';
describe('bug', () => {
let host: Host;
let fixture: ComponentFixture<Host>;
@Component({
selector: 'child',
template: ``,
})
class Child {}
@Component({
template: `
<ng-container *ngFor="let show of shows">
<child *ngIf="show"></child>
</ng-container>
<button (click)="shows[1] = true">show</button>`
})
class Host {
shows = [false, false];
@ViewChildren(Child) children: QueryList<Child>;
constructor() {
setTimeout(() => this.shows[0] = true, 50);
}
}
fit('test', fakeAsync(() => {
TestBed.configureTestingModule({
imports: [
CommonModule,
],
declarations: [
Host, Child,
],
providers: [{
provide: ComponentFixtureAutoDetect,
useValue: true,
}]
});
fixture = TestBed.createComponent(Host);
host = fixture.componentInstance;
tick(10);
expect(host.children.length).toEqual(0);
tick(50);
expect(host.children.length).toEqual(1);
const button = fixture.debugElement.query(By.css('button'));
button.triggerEventHandler('click', new Event('click'));
tick(50);
// fixture.detectChanges();
expect(host.children.length).toEqual(2); // fails here
}));
});
【问题讨论】:
标签: angular angular5 angular2-testing angular2-changedetection