What is the difference between angular testing async+whenStable and fakeAsync+tick?












4















I understand that the async and fakeAsync methods setup some kind of listener that records all async operations so that the angular testing framework can use whenStable and tick() to manage waiting for all that stuff to finish. I think thats correct?



The thing I am struggling to understand is whether there is actually an execution order difference - because if not why offer both?



This has brought me to learning about JS macro tasks and Micro tasks and I am wondering if this area is where the two approaches differ?










share|improve this question

























  • You may also be interested in stackoverflow.com/questions/42971537/…

    – Amit Chigadani
    Nov 23 '18 at 12:09
















4















I understand that the async and fakeAsync methods setup some kind of listener that records all async operations so that the angular testing framework can use whenStable and tick() to manage waiting for all that stuff to finish. I think thats correct?



The thing I am struggling to understand is whether there is actually an execution order difference - because if not why offer both?



This has brought me to learning about JS macro tasks and Micro tasks and I am wondering if this area is where the two approaches differ?










share|improve this question

























  • You may also be interested in stackoverflow.com/questions/42971537/…

    – Amit Chigadani
    Nov 23 '18 at 12:09














4












4








4








I understand that the async and fakeAsync methods setup some kind of listener that records all async operations so that the angular testing framework can use whenStable and tick() to manage waiting for all that stuff to finish. I think thats correct?



The thing I am struggling to understand is whether there is actually an execution order difference - because if not why offer both?



This has brought me to learning about JS macro tasks and Micro tasks and I am wondering if this area is where the two approaches differ?










share|improve this question
















I understand that the async and fakeAsync methods setup some kind of listener that records all async operations so that the angular testing framework can use whenStable and tick() to manage waiting for all that stuff to finish. I think thats correct?



The thing I am struggling to understand is whether there is actually an execution order difference - because if not why offer both?



This has brought me to learning about JS macro tasks and Micro tasks and I am wondering if this area is where the two approaches differ?







angular testing






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 23 '18 at 12:10









Amit Chigadani

10.7k53052




10.7k53052










asked Nov 23 '18 at 9:36









CraigCraig

402315




402315













  • You may also be interested in stackoverflow.com/questions/42971537/…

    – Amit Chigadani
    Nov 23 '18 at 12:09



















  • You may also be interested in stackoverflow.com/questions/42971537/…

    – Amit Chigadani
    Nov 23 '18 at 12:09

















You may also be interested in stackoverflow.com/questions/42971537/…

– Amit Chigadani
Nov 23 '18 at 12:09





You may also be interested in stackoverflow.com/questions/42971537/…

– Amit Chigadani
Nov 23 '18 at 12:09












1 Answer
1






active

oldest

votes


















4














Here's an abstract from Testing Asynchronous Code - CodeCraft




async + whenStable:



Consider this piece of code:



it('Button label via async() and whenStable()', async(() => { 
fixture.detectChanges();
expect(el.nativeElement.textContent.trim()).toBe('Login');
spyOn(authService, 'isAuthenticated').and.returnValue(Promise.resolve(true));
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(el.nativeElement.textContent.trim()).toBe('Logout');
});
component.ngOnInit();
}));


async function executes the code inside its body in a special async test zone. This intercepts and keeps track of all promises created in its body.



Only when all of those pending promises have been resolved does it then resolves the promise returned from whenStable.



You can use this to avoid using Jasmine's spy mechanism of detecting when a promise has been resolved.



This mechanism is slightly better than using the plain Jasmine solution but there is another version which gives us fine grained control and also allows us to lay out our test code as if it were synchronous.






fakeAsync + tick:



Now consider this piece of code:



it('Button label via fakeAsync() and tick()', fakeAsync(() => { 
expect(el.nativeElement.textContent.trim()).toBe('');
fixture.detectChanges();
expect(el.nativeElement.textContent.trim()).toBe('Login');
spyOn(authService, 'isAuthenticated').and.returnValue(Promise.resolve(true));
component.ngOnInit();

tick();
fixture.detectChanges();
expect(el.nativeElement.textContent.trim()).toBe('Logout');
}));


Just like async, the fakeAsync function executes the code inside its body in a special fake async test zone. This intercepts and keeps track of all promises created in its body.



The tick() function blocks execution and simulates the passage of time until all pending asynchronous activities complete.



So when we call tick() the application sits and waits for the promises to be resolved and then lets execution move to the next line.



The main advantage of using this is that it makes the code more linear as if we were executing synchronous code, there are no callbacks to confuse the mind and everything is simpler to understand.



Conclusion:



There are three mechanisms we can use to test asynchronous code:




  1. The jasmine's done function and spy callbacks. This works but expects us to know about all the promises in our application and be able to hook into them.


  2. We can use the Angular async and whenStable functions, we don’t need to track the promises ourselves but we still need to lay our code out via callback functions which can be hard to read.


  3. We can use the Angular fakeAsync and tick functions, this additionally lets us lay out our async test code as if it were synchronous.



These points would make you think that why use async + whenStable if it's hard to read. Why not simply use fakeAsync + tick instead? Well one of the reasons would be beause of this:




Important
fakeAsync does have some drawbacks, it doesn’t track XHR requests for instance.




You can read more about this on this GitHub Thread.






share|improve this answer


























  • What I am understanding from that is that they are exactly the same but one is a nicer syntax which begs the question why have the worse syntax as an option? also you can still do fixture.whenStable inside a fakeAsync zone but I dont know if that works?

    – Craig
    Nov 23 '18 at 10:04








  • 1





    Let me try to answer that by updating the answer.

    – SiddAjmera
    Nov 23 '18 at 10:05











  • @Craig, I've updated the answer. Hope it's clearer now.

    – SiddAjmera
    Nov 23 '18 at 10:28











  • You're awesome.

    – Craig
    Nov 23 '18 at 10:36












Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53444002%2fwhat-is-the-difference-between-angular-testing-asyncwhenstable-and-fakeasyncti%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









4














Here's an abstract from Testing Asynchronous Code - CodeCraft




async + whenStable:



Consider this piece of code:



it('Button label via async() and whenStable()', async(() => { 
fixture.detectChanges();
expect(el.nativeElement.textContent.trim()).toBe('Login');
spyOn(authService, 'isAuthenticated').and.returnValue(Promise.resolve(true));
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(el.nativeElement.textContent.trim()).toBe('Logout');
});
component.ngOnInit();
}));


async function executes the code inside its body in a special async test zone. This intercepts and keeps track of all promises created in its body.



Only when all of those pending promises have been resolved does it then resolves the promise returned from whenStable.



You can use this to avoid using Jasmine's spy mechanism of detecting when a promise has been resolved.



This mechanism is slightly better than using the plain Jasmine solution but there is another version which gives us fine grained control and also allows us to lay out our test code as if it were synchronous.






fakeAsync + tick:



Now consider this piece of code:



it('Button label via fakeAsync() and tick()', fakeAsync(() => { 
expect(el.nativeElement.textContent.trim()).toBe('');
fixture.detectChanges();
expect(el.nativeElement.textContent.trim()).toBe('Login');
spyOn(authService, 'isAuthenticated').and.returnValue(Promise.resolve(true));
component.ngOnInit();

tick();
fixture.detectChanges();
expect(el.nativeElement.textContent.trim()).toBe('Logout');
}));


Just like async, the fakeAsync function executes the code inside its body in a special fake async test zone. This intercepts and keeps track of all promises created in its body.



The tick() function blocks execution and simulates the passage of time until all pending asynchronous activities complete.



So when we call tick() the application sits and waits for the promises to be resolved and then lets execution move to the next line.



The main advantage of using this is that it makes the code more linear as if we were executing synchronous code, there are no callbacks to confuse the mind and everything is simpler to understand.



Conclusion:



There are three mechanisms we can use to test asynchronous code:




  1. The jasmine's done function and spy callbacks. This works but expects us to know about all the promises in our application and be able to hook into them.


  2. We can use the Angular async and whenStable functions, we don’t need to track the promises ourselves but we still need to lay our code out via callback functions which can be hard to read.


  3. We can use the Angular fakeAsync and tick functions, this additionally lets us lay out our async test code as if it were synchronous.



These points would make you think that why use async + whenStable if it's hard to read. Why not simply use fakeAsync + tick instead? Well one of the reasons would be beause of this:




Important
fakeAsync does have some drawbacks, it doesn’t track XHR requests for instance.




You can read more about this on this GitHub Thread.






share|improve this answer


























  • What I am understanding from that is that they are exactly the same but one is a nicer syntax which begs the question why have the worse syntax as an option? also you can still do fixture.whenStable inside a fakeAsync zone but I dont know if that works?

    – Craig
    Nov 23 '18 at 10:04








  • 1





    Let me try to answer that by updating the answer.

    – SiddAjmera
    Nov 23 '18 at 10:05











  • @Craig, I've updated the answer. Hope it's clearer now.

    – SiddAjmera
    Nov 23 '18 at 10:28











  • You're awesome.

    – Craig
    Nov 23 '18 at 10:36
















4














Here's an abstract from Testing Asynchronous Code - CodeCraft




async + whenStable:



Consider this piece of code:



it('Button label via async() and whenStable()', async(() => { 
fixture.detectChanges();
expect(el.nativeElement.textContent.trim()).toBe('Login');
spyOn(authService, 'isAuthenticated').and.returnValue(Promise.resolve(true));
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(el.nativeElement.textContent.trim()).toBe('Logout');
});
component.ngOnInit();
}));


async function executes the code inside its body in a special async test zone. This intercepts and keeps track of all promises created in its body.



Only when all of those pending promises have been resolved does it then resolves the promise returned from whenStable.



You can use this to avoid using Jasmine's spy mechanism of detecting when a promise has been resolved.



This mechanism is slightly better than using the plain Jasmine solution but there is another version which gives us fine grained control and also allows us to lay out our test code as if it were synchronous.






fakeAsync + tick:



Now consider this piece of code:



it('Button label via fakeAsync() and tick()', fakeAsync(() => { 
expect(el.nativeElement.textContent.trim()).toBe('');
fixture.detectChanges();
expect(el.nativeElement.textContent.trim()).toBe('Login');
spyOn(authService, 'isAuthenticated').and.returnValue(Promise.resolve(true));
component.ngOnInit();

tick();
fixture.detectChanges();
expect(el.nativeElement.textContent.trim()).toBe('Logout');
}));


Just like async, the fakeAsync function executes the code inside its body in a special fake async test zone. This intercepts and keeps track of all promises created in its body.



The tick() function blocks execution and simulates the passage of time until all pending asynchronous activities complete.



So when we call tick() the application sits and waits for the promises to be resolved and then lets execution move to the next line.



The main advantage of using this is that it makes the code more linear as if we were executing synchronous code, there are no callbacks to confuse the mind and everything is simpler to understand.



Conclusion:



There are three mechanisms we can use to test asynchronous code:




  1. The jasmine's done function and spy callbacks. This works but expects us to know about all the promises in our application and be able to hook into them.


  2. We can use the Angular async and whenStable functions, we don’t need to track the promises ourselves but we still need to lay our code out via callback functions which can be hard to read.


  3. We can use the Angular fakeAsync and tick functions, this additionally lets us lay out our async test code as if it were synchronous.



These points would make you think that why use async + whenStable if it's hard to read. Why not simply use fakeAsync + tick instead? Well one of the reasons would be beause of this:




Important
fakeAsync does have some drawbacks, it doesn’t track XHR requests for instance.




You can read more about this on this GitHub Thread.






share|improve this answer


























  • What I am understanding from that is that they are exactly the same but one is a nicer syntax which begs the question why have the worse syntax as an option? also you can still do fixture.whenStable inside a fakeAsync zone but I dont know if that works?

    – Craig
    Nov 23 '18 at 10:04








  • 1





    Let me try to answer that by updating the answer.

    – SiddAjmera
    Nov 23 '18 at 10:05











  • @Craig, I've updated the answer. Hope it's clearer now.

    – SiddAjmera
    Nov 23 '18 at 10:28











  • You're awesome.

    – Craig
    Nov 23 '18 at 10:36














4












4








4







Here's an abstract from Testing Asynchronous Code - CodeCraft




async + whenStable:



Consider this piece of code:



it('Button label via async() and whenStable()', async(() => { 
fixture.detectChanges();
expect(el.nativeElement.textContent.trim()).toBe('Login');
spyOn(authService, 'isAuthenticated').and.returnValue(Promise.resolve(true));
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(el.nativeElement.textContent.trim()).toBe('Logout');
});
component.ngOnInit();
}));


async function executes the code inside its body in a special async test zone. This intercepts and keeps track of all promises created in its body.



Only when all of those pending promises have been resolved does it then resolves the promise returned from whenStable.



You can use this to avoid using Jasmine's spy mechanism of detecting when a promise has been resolved.



This mechanism is slightly better than using the plain Jasmine solution but there is another version which gives us fine grained control and also allows us to lay out our test code as if it were synchronous.






fakeAsync + tick:



Now consider this piece of code:



it('Button label via fakeAsync() and tick()', fakeAsync(() => { 
expect(el.nativeElement.textContent.trim()).toBe('');
fixture.detectChanges();
expect(el.nativeElement.textContent.trim()).toBe('Login');
spyOn(authService, 'isAuthenticated').and.returnValue(Promise.resolve(true));
component.ngOnInit();

tick();
fixture.detectChanges();
expect(el.nativeElement.textContent.trim()).toBe('Logout');
}));


Just like async, the fakeAsync function executes the code inside its body in a special fake async test zone. This intercepts and keeps track of all promises created in its body.



The tick() function blocks execution and simulates the passage of time until all pending asynchronous activities complete.



So when we call tick() the application sits and waits for the promises to be resolved and then lets execution move to the next line.



The main advantage of using this is that it makes the code more linear as if we were executing synchronous code, there are no callbacks to confuse the mind and everything is simpler to understand.



Conclusion:



There are three mechanisms we can use to test asynchronous code:




  1. The jasmine's done function and spy callbacks. This works but expects us to know about all the promises in our application and be able to hook into them.


  2. We can use the Angular async and whenStable functions, we don’t need to track the promises ourselves but we still need to lay our code out via callback functions which can be hard to read.


  3. We can use the Angular fakeAsync and tick functions, this additionally lets us lay out our async test code as if it were synchronous.



These points would make you think that why use async + whenStable if it's hard to read. Why not simply use fakeAsync + tick instead? Well one of the reasons would be beause of this:




Important
fakeAsync does have some drawbacks, it doesn’t track XHR requests for instance.




You can read more about this on this GitHub Thread.






share|improve this answer















Here's an abstract from Testing Asynchronous Code - CodeCraft




async + whenStable:



Consider this piece of code:



it('Button label via async() and whenStable()', async(() => { 
fixture.detectChanges();
expect(el.nativeElement.textContent.trim()).toBe('Login');
spyOn(authService, 'isAuthenticated').and.returnValue(Promise.resolve(true));
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(el.nativeElement.textContent.trim()).toBe('Logout');
});
component.ngOnInit();
}));


async function executes the code inside its body in a special async test zone. This intercepts and keeps track of all promises created in its body.



Only when all of those pending promises have been resolved does it then resolves the promise returned from whenStable.



You can use this to avoid using Jasmine's spy mechanism of detecting when a promise has been resolved.



This mechanism is slightly better than using the plain Jasmine solution but there is another version which gives us fine grained control and also allows us to lay out our test code as if it were synchronous.






fakeAsync + tick:



Now consider this piece of code:



it('Button label via fakeAsync() and tick()', fakeAsync(() => { 
expect(el.nativeElement.textContent.trim()).toBe('');
fixture.detectChanges();
expect(el.nativeElement.textContent.trim()).toBe('Login');
spyOn(authService, 'isAuthenticated').and.returnValue(Promise.resolve(true));
component.ngOnInit();

tick();
fixture.detectChanges();
expect(el.nativeElement.textContent.trim()).toBe('Logout');
}));


Just like async, the fakeAsync function executes the code inside its body in a special fake async test zone. This intercepts and keeps track of all promises created in its body.



The tick() function blocks execution and simulates the passage of time until all pending asynchronous activities complete.



So when we call tick() the application sits and waits for the promises to be resolved and then lets execution move to the next line.



The main advantage of using this is that it makes the code more linear as if we were executing synchronous code, there are no callbacks to confuse the mind and everything is simpler to understand.



Conclusion:



There are three mechanisms we can use to test asynchronous code:




  1. The jasmine's done function and spy callbacks. This works but expects us to know about all the promises in our application and be able to hook into them.


  2. We can use the Angular async and whenStable functions, we don’t need to track the promises ourselves but we still need to lay our code out via callback functions which can be hard to read.


  3. We can use the Angular fakeAsync and tick functions, this additionally lets us lay out our async test code as if it were synchronous.



These points would make you think that why use async + whenStable if it's hard to read. Why not simply use fakeAsync + tick instead? Well one of the reasons would be beause of this:




Important
fakeAsync does have some drawbacks, it doesn’t track XHR requests for instance.




You can read more about this on this GitHub Thread.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 23 '18 at 10:27

























answered Nov 23 '18 at 10:01









SiddAjmeraSiddAjmera

16k31239




16k31239













  • What I am understanding from that is that they are exactly the same but one is a nicer syntax which begs the question why have the worse syntax as an option? also you can still do fixture.whenStable inside a fakeAsync zone but I dont know if that works?

    – Craig
    Nov 23 '18 at 10:04








  • 1





    Let me try to answer that by updating the answer.

    – SiddAjmera
    Nov 23 '18 at 10:05











  • @Craig, I've updated the answer. Hope it's clearer now.

    – SiddAjmera
    Nov 23 '18 at 10:28











  • You're awesome.

    – Craig
    Nov 23 '18 at 10:36



















  • What I am understanding from that is that they are exactly the same but one is a nicer syntax which begs the question why have the worse syntax as an option? also you can still do fixture.whenStable inside a fakeAsync zone but I dont know if that works?

    – Craig
    Nov 23 '18 at 10:04








  • 1





    Let me try to answer that by updating the answer.

    – SiddAjmera
    Nov 23 '18 at 10:05











  • @Craig, I've updated the answer. Hope it's clearer now.

    – SiddAjmera
    Nov 23 '18 at 10:28











  • You're awesome.

    – Craig
    Nov 23 '18 at 10:36

















What I am understanding from that is that they are exactly the same but one is a nicer syntax which begs the question why have the worse syntax as an option? also you can still do fixture.whenStable inside a fakeAsync zone but I dont know if that works?

– Craig
Nov 23 '18 at 10:04







What I am understanding from that is that they are exactly the same but one is a nicer syntax which begs the question why have the worse syntax as an option? also you can still do fixture.whenStable inside a fakeAsync zone but I dont know if that works?

– Craig
Nov 23 '18 at 10:04






1




1





Let me try to answer that by updating the answer.

– SiddAjmera
Nov 23 '18 at 10:05





Let me try to answer that by updating the answer.

– SiddAjmera
Nov 23 '18 at 10:05













@Craig, I've updated the answer. Hope it's clearer now.

– SiddAjmera
Nov 23 '18 at 10:28





@Craig, I've updated the answer. Hope it's clearer now.

– SiddAjmera
Nov 23 '18 at 10:28













You're awesome.

– Craig
Nov 23 '18 at 10:36





You're awesome.

– Craig
Nov 23 '18 at 10:36




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53444002%2fwhat-is-the-difference-between-angular-testing-asyncwhenstable-and-fakeasyncti%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

If I really need a card on my start hand, how many mulligans make sense? [duplicate]

Alcedinidae

Can an atomic nucleus contain both particles and antiparticles? [duplicate]