tl;博士
在几乎所有情况下,它们都可以互换使用,但最好使用 fakeAsync()/tick() 组合,除非您需要进行 XHR 调用,在这种情况下,您必须使用 async()/whenStable() 组合,因为 fakeAsync() 不支持 XHR来电。
在大多数情况下,它们可以互换使用。除了外部模板和样式未内联编译到组件中以进行测试的组件的情况外,我想不出任何一个必需的组件(即使用 SystemJS)。使用 SystemJS 时,会对外部模板和样式进行 XHR 调用。 fakeAsync() 在有 XHR 调用时不能使用。另一方面,在使用 Webpack 时,外部模板和样式会被内联编译,因此您可以使用 fakeAsync()。
除此之外,我认为这是风格偏好的问题。我可以说的一件事是假设您需要进行多个异步调用,例如在this example 中。您需要嵌套的 fixture.whenStable() 调用,当它们变得如此之深时,它们会开始看起来很丑陋。
someAsyncAction();
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(something)
changeSomethingElseAsynchronously();
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(something);
anotherAsyncAction();
fixture.whenStable().then(() => {
fixture.detectChanges()
expect(somthingeElse)
})
})
})
如果没有所有那些fixture.whenStable()s 和看起来同步的代码,这可能看起来更简洁(并且更容易推理)。
tick();
fixture.detectChanges();
expect(something)
changeSomethingAsynchronously()
tick();
fixture.detectChanges();
expect(somethingElse)
changeSomethingAsynchronously()
tick();
fixture.detectChanges();
expect(somethingElse);
我可能要补充的另一件事是我的OCD 部分总是需要检查我在fixture.whenStable() 中的调用是否被调用
fixture.whenStable().then(() => {
expect(...)
console.log('called...')
})
假设您忘记将测试包含在 async 中。没有它,测试将在fixture.whenStable 分辨率之前完成,你永远不会知道。看起来测试通过了,这是一个误报。实际发生的事情是断言甚至从未被调用过。
出于这个原因,我实际上已经离开了async。但是,如果您喜欢这种风格,并且相信自己始终将测试包装在 async 中,那么请坚持下去。但是使用fakeAsync,一切都是同步调用的,所以断言不可能不被调用。