Sé que la función tick() utiliza fakeAsync() . Y también puedo usar fixture.whenStable().then() con async() y fakeAsync() también.
Quiero saber el caso de uso exacto para ambos. ¿Alguien puede explicar esto con ejemplos?
Nota: quiero usar Fake Service o Stub en ambos escenarios.
En casi todos los casos, se pueden usar indistintamente, pero se prefiere usar fakeAsync()/tick() a menos que necesite hacer una llamada XHR, en cuyo caso DEBE usar el combo async()/whenStable() , como fakeAsync() no admite llamadas XHR.
En su mayor parte, se pueden usar indistintamente. No puedo pensar en nada en la parte superior de mi cabeza en el que se requiera uno sobre el otro, excepto en el caso de componentes cuyas plantillas y estilos externos no se compilan en línea en el componente para la prueba (es decir, usando SystemJS). Cuando se usa SystemJS, se realizan llamadas XHR para las plantillas y estilos externos. fakeAsync() no se puede usar cuando se realizan llamadas XHR. Por otro lado, cuando usa Webpack, las plantillas y estilos externos se compilan en línea, por lo que puede usar fakeAsync() .
Aparte de eso, creo que es una cuestión de preferencia de estilo. Una cosa que puedo decir es que imagine que necesita realizar varias llamadas asíncronas, como en este ejemplo . Necesita llamadas fixture.whenStable() anidadas, que pueden comenzar a verse bastante feas cuando se vuelven tan profundas.
someAsyncAction(); fixture.whenStable().then(() => { fixture.detectChanges(); expect(something) changeSomethingElseAsynchronously(); fixture.whenStable().then(() => { fixture.detectChanges(); expect(something); anotherAsyncAction(); fixture.whenStable().then(() => { fixture.detectChanges() expect(somthingeElse) }) }) }) Esto podría parecer más limpio (y más fácil de razonar) sin todos esos fixture.whenStable() sy código que parece sincrónico.
tick(); fixture.detectChanges(); expect(something) changeSomethingAsynchronously() tick(); fixture.detectChanges(); expect(somethingElse) changeSomethingAsynchronously() tick(); fixture.detectChanges(); expect(somethingElse); Otra cosa que podría agregar es que mi parte de TOC siempre necesita verificar que mis llamadas en el dispositivo. Cuando se llama a fixture.whenStable()
fixture.whenStable().then(() => { expect(...) console.log('called...') }) Imagine que olvidó envolver la prueba en async . Sin eso, la prueba se completará antes que el fixture.whenStable . Cuando la resolución sea estable, y nunca lo sabrá. Parecerá que la prueba pasó, que es un falso positivo. Lo que realmente sucedió es que la afirmación ni siquiera fue llamada.
Por esta razón, en realidad me he estado alejando de async . Pero si le gusta ese estilo y confía en que siempre envuelve la prueba en async , entonces quédese con él. Pero con fakeAsync , todo se llama sincrónicamente, por lo que no hay posibilidad de que no se llame a la afirmación.
Use async o waitForAcync cuando tengamos una llamada HTTP y use fakeAsync cuando no haya una llamada HTTP pero sea observable O prometa o setTimeout (que no usan llamadas HTTP).
Básicamente, fakeAsync con la función tick avanzará el tiempo en un número específico de milisegundos, por lo que tick(50000) ejecutará cualquier tarea asíncrona que ocurra en 50 segundos y se completará a simple vista. porque avanza el tiempo en 50 segundos. mire el ejemplo a continuación, ya que setTimeout necesita 50 segundos para ejecutarse en caso de async o waitForAcync, pero fakeAsynch no tomará tiempo.
describe('this test', () => { it('looks async but is synchronous', fakeAsync(() => { let flag = false; setTimeout(() => { flag = true; }, 50000); expect(flag).toBe(false); tick(25000); expect(flag).toBe(false); tick(25000); expect(flag).toBe(true); })); });