fakeAsync 不应该阻止自动订阅完成吗?
Shouldn't fakeAsync prevent automatic subscription completion?
我认为通过使用 fakeAsync
包装器,我的测试不会自动 运行 订阅并且我会通过手动调用 tick
来控制那部分,但是那似乎并非如此。例如,使用这种方法:
foo(): void {
of([1, 2, 3]).subscribe({
next: () => {
console.info('Subscription completed.')
this.value = true
},
error: (err: unknown) => console.error('error called')
})
}
并使用此规范进行测试:
it('should foo', fakeAsync(() => {
component.foo()
expect(component.value).toBeFalse()
}))
我看到打印了订阅完成消息,因此预期失败了。我以为 foo 方法会被调用,但订阅不会完成,直到我将 tick()
调用放入规范中。
我做错了什么?
滴答只是控制时间流逝的方式。来自 Angular 文档。
If you omit the tickOptions parameter (tick(100))), then tickOptions defaults to {processNewMacroTasksSynchronously: true}.
您关于所有可观察对象都是异步的假设是错误的。
Observables 可以是异步的,也可以是同步的,具体取决于底层实现。换句话说,如果源是同步的,则反应流是同步的,除非您明确地将它们设为异步。
一些示例:
//Synchronous
of(1,2)
.subscribe(console.log);
//asynchronous because of async source
interval(1000)
.subscribe(console.log);
//aynchronous because one stream is async (interval)
of(1,2)
.pipe(
mergeMap(x => interval(1000).pipe(take(2)))
)
.subscribe(console.log);
//async because we make it async
of(1,2, asyncScheduler)
.subscribe(console.log);
TLDR:因为 of([1, 2, 3])
是一个异步源,您将无法控制它何时以 fakeAsync
完成。
我认为通过使用 fakeAsync
包装器,我的测试不会自动 运行 订阅并且我会通过手动调用 tick
来控制那部分,但是那似乎并非如此。例如,使用这种方法:
foo(): void {
of([1, 2, 3]).subscribe({
next: () => {
console.info('Subscription completed.')
this.value = true
},
error: (err: unknown) => console.error('error called')
})
}
并使用此规范进行测试:
it('should foo', fakeAsync(() => {
component.foo()
expect(component.value).toBeFalse()
}))
我看到打印了订阅完成消息,因此预期失败了。我以为 foo 方法会被调用,但订阅不会完成,直到我将 tick()
调用放入规范中。
我做错了什么?
滴答只是控制时间流逝的方式。来自 Angular 文档。
If you omit the tickOptions parameter (tick(100))), then tickOptions defaults to {processNewMacroTasksSynchronously: true}.
您关于所有可观察对象都是异步的假设是错误的。
Observables 可以是异步的,也可以是同步的,具体取决于底层实现。换句话说,如果源是同步的,则反应流是同步的,除非您明确地将它们设为异步。
一些示例:
//Synchronous
of(1,2)
.subscribe(console.log);
//asynchronous because of async source
interval(1000)
.subscribe(console.log);
//aynchronous because one stream is async (interval)
of(1,2)
.pipe(
mergeMap(x => interval(1000).pipe(take(2)))
)
.subscribe(console.log);
//async because we make it async
of(1,2, asyncScheduler)
.subscribe(console.log);
TLDR:因为 of([1, 2, 3])
是一个异步源,您将无法控制它何时以 fakeAsync
完成。