该问题是上一个问题(linked here)的延续。我仍在为编写Angular测试的简单教程而使用相同的文件。新问题与setTimeout函数有关。
在ngOnInit和ngAfterViewInit上,我都实现了setTimeout(我将在以后编写的其他测试中做到这一点,因此,这只是创建一个基本示例)。内部的函数设置通过HTML文件传递给子组件的变量的值。然后检查该子组件的变量的特定值。
我已经尝试使用tick(value)和Fixture.detectChanges()来尝试触发setTimeout函数的内容,但是该值仍未定义(请参见代码段)。
random.test.component.ts
public dataThatGetsDelayed: any;
constructor() {
}
ngOnInit() {
setTimeout(() => {
this.dataThatGetsDelayed = "OnInit";
}, 100);
}
ngAfterViewInit() {
setTimeout(() => {
this.dataThatGetsDelayed = "AfterView";
}, 100);
}
random.test.component.html
[variableThatStoresDelayedData]="dataThatGetsDelayed"
random.test.component.child.ts
@Input() variableThatStoresDelayedData: any;
random.test.file.spec.ts
it('Testing if receiving input works properly with a time delay in ngOnInit', fakeAsync(() => {
const componentInThePage: TestComponentChild = fixture.debugElement.query(By.directive(TestComponentChild)).componentInstance;
expect(componentInThePage).toBeTruthy();
tick(100);
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(componentInThePage.variableThatStoresDelayedData).toEqual("OnInit");
});
}));
it('Testing if receiving input works properly with a time delay in ngAfterViewInit', fakeAsync(() => {
const componentInThePage: TestComponentChild = fixture.debugElement.query(By.directive(TestComponentChild)).componentInstance;
expect(componentInThePage).toBeTruthy();
//tick(100);
//component.ngAfterViewInit();
fixture.whenStable().then(() => {
expect(componentInThePage.variableThatStoresDelayedData).toEqual("AfterView");
});
}));
我读到我应该在最后使用whenStable,但是我现在知道这完全被忽略了。否则,我将收到错误消息“预期未定义的值等于'OnInit'/'AfterView'”。我省略了第二个刻度,因为它会导致错误“ 1个计时器仍在队列中”。
如何告诉程序等待,直到在setTimeout函数中设置了值?
答案 0 :(得分:0)
好的,因此,通过一些研究和实验,我找到了解决方案。代码注释解释了更详细的信息:
random.test.component.ts
public dataThatGetsDelayed: any = "Initial value"; //This is just to show how the value changes.
constructor(private detectorReference: ChangeDetectorRef) {
//The detectorReference is used in ngAfterViewInit
}
ngOnInit() {
setTimeout(() => {
this.dataThatGetsDelayed = "OnInit";
}, 100);
}
ngAfterViewInit() {
setTimeout(() => {
this.dataThatGetsDelayed = "AfterView";
this.detectorReference.detectChanges(); //Needed to stop the error about changing the value.
}, 200);
}
(感谢this的帮助!)
random.test.file.spec.ts
//This test is for the ngOnInit function
it('Testing if receiving input works properly with a time delay in ngOnInit', fakeAsync(() => {
const componentInThePage: TestComponentChild = fixture.debugElement.query(By.directive(TestComponentChild)).componentInstance;
expect(componentInThePage).toBeTruthy();
expect(componentInThePage.variableThatStoresDelayedData).toEqual("Initial value");
component.ngOnInit();
//tick(99); - This doesn't /quite/ run out the setTimeout function from the ngOnInit function.
tick(100); //This does, though.
fixture.detectChanges();
expect(componentInThePage.variableThatStoresDelayedData).toEqual("OnInit");
}));
//This test is for the ngAfterViewInit function. Note that the value isn't set with ngOnInit first;
//only the explicit method call will perform the desired action.
it('Testing if receiving input works properly with a time delay in ngAfterViewInit', fakeAsync(() => {
const componentInThePage: TestComponentChild = fixture.debugElement.query(By.directive(TestComponentChild)).componentInstance;
expect(componentInThePage).toBeTruthy();
expect(componentInThePage.variableThatStoresDelayedData).toEqual("Initial value");
component.ngAfterViewInit();
//tick(199); - Again, this doesn't /quite/ run out the setTimeout.
tick(200); //But, once again, this does.
fixture.detectChanges();
expect(componentInThePage.variableThatStoresDelayedData).toEqual("AfterView");
}));
希望这对以后的人有帮助!