使用 setTimeout 时测试从其他组件接收输入
Testing receiving input from other components when using setTimeout
这个问题是上一个问题 () 的延续。我仍在使用相同的文件,目的是为 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,但我现在知道这完全被忽略了。否则,我会得到错误 "Expected undefined to equal 'OnInit'/'AfterView'"。我省略了第二个勾号,因为它会导致错误“1 个计时器仍在队列中”。
如何告诉程序等待 setTimeout 函数中的值设置?
好的,通过一些研究和实验,我找到了解决方案。代码注释解释了更详细的信息:
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);
}
(感谢 来源的帮助!)
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");
}));
希望这对以后的人有所帮助!
这个问题是上一个问题 (
在 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,但我现在知道这完全被忽略了。否则,我会得到错误 "Expected undefined to equal 'OnInit'/'AfterView'"。我省略了第二个勾号,因为它会导致错误“1 个计时器仍在队列中”。
如何告诉程序等待 setTimeout 函数中的值设置?
好的,通过一些研究和实验,我找到了解决方案。代码注释解释了更详细的信息:
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);
}
(感谢
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");
}));
希望这对以后的人有所帮助!