What is the difference between angular testing async+whenStable and fakeAsync+tick?
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
add a comment |
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
You may also be interested in stackoverflow.com/questions/42971537/…
– Amit Chigadani
Nov 23 '18 at 12:09
add a comment |
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
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
angular testing
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
add a comment |
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
add a comment |
1 Answer
1
active
oldest
votes
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:
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.We can use the Angular
async
andwhenStable
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.We can use the Angular
fakeAsync
andtick
functions, this additionally lets us lay out ourasync
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.
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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:
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.We can use the Angular
async
andwhenStable
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.We can use the Angular
fakeAsync
andtick
functions, this additionally lets us lay out ourasync
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.
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
add a comment |
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:
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.We can use the Angular
async
andwhenStable
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.We can use the Angular
fakeAsync
andtick
functions, this additionally lets us lay out ourasync
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.
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
add a comment |
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:
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.We can use the Angular
async
andwhenStable
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.We can use the Angular
fakeAsync
andtick
functions, this additionally lets us lay out ourasync
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.
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:
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.We can use the Angular
async
andwhenStable
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.We can use the Angular
fakeAsync
andtick
functions, this additionally lets us lay out ourasync
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.
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
You may also be interested in stackoverflow.com/questions/42971537/…
– Amit Chigadani
Nov 23 '18 at 12:09