-
-
Notifications
You must be signed in to change notification settings - Fork 770
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
useFakeTimers in combination with async callbacks #1739
Comments
Ran into a similar problem. My proposal would be to add a new option for I might even come up with a PR this week if that's agreeable? |
That would be cool! https://github.com/sinonjs/lolex is where to point your PR. |
@dominykas Make sure you don't start creating a PR until you have read through sinonjs/fake-timers#105! There is an extended discussion there, and it has basically been stalled since July, which is unfortunate, as @kylefleming has done an extensive amount of work and there is lots of good discussion. His PR seems to do what a lot of people want (judging from the comments). I am not quite sure where or why it stalled, but I remember it all going a bit over my head details wise, and it's now a long time since it was discussed, so I am a bit reluctant to dig into it. Maybe it's time some new eyes had a look at it ... (hint, hint 👀). |
Thanks, will take a look - prior art always good :) |
That is a very well researched issue indeed - I'll need some time to take all of the ideas in, as well as the discussions in a related sinonjs/fake-timers#114. I think it got stalled waiting for feedback. I think the implementation is roughly what I was going to do (i.e. an async tick returns a promise and actually makes the event loop take a break using I do have to dig deeper to understand the non-native promise library behaviors, esp. in the browsers. I'll try to get back to this ASAP - first thing is to test whether that PR solves the problem I have (I suspect it does). |
I'm not entirely sure what's better - making the behavior "async" globally or forcing the developer to decide on every call. The latter one is probably on the safe side from sinonjs/lolex point of view. |
I'm not sure there's a "safe" call involved here. My proposal is to not make it global - it's to make the behavior consistent for each My proposal mostly comes from what one of my colleagues said, and I tend to somewhat agree - clock ticks are async in JS, so they should probably behave that way when mocked too. I once thought that maybe sinon deliberately made the clock the way it is precisely because it wanted to make the code look more sync (sync code is a lot easier to grok under certain use cases - the test script being one of them). However with async/await that is no longer necessary. Sorry, I still haven't had a chance to properly digest the implementation and what's missing in sinonjs/fake-timers#105, but I do wonder if there's a way to get a decision on which API is better in the meantime? |
I am in favour of expanding the API with For a couple of reasons:
install({ async: someBooleanValue }).
// ... thousands of lines of tests
// how does this behave?
clock.tick(); |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
No no no! I promise I'll get back to this! |
Thanks, bot :) |
Unkept promises? :P |
Rather rejected Promises 😜 |
No @shokmaster, you have an incorrectly configured timeout value. |
After struggling with a similar problem all morning, I found a dirty workaround that works when async calls are stubbed. The solution is to simply call await in the test context to give a chance to promises to resolve. Technically, you would need to call await once for every level in your promise chain. Here is a version of your code that should work:
Note that I'm not "happy" with that solution but it works. I'm also not 100% sure of what is happening under the cover - if anyone could give a better explanation, I would be grateful. |
I see |
AFAIK this has been implemented in Lolex by @dominykas (thank you) and exposed in Sinon's API, ref all the
So unless someone says otherwise, this is done :) |
I'm currently trying to test an
async
method which sets a new timeout after it has completed executing. Using sinon's fake timers, this can be a minor headache. Basically I'm doing the following:On the console you can see what happens:
I've been able to work around the issue by doing the following:
// some more work
comment)Now the log looks like this:
So, here's my suggestion:
Provide a method similar to
runAll()
(lets call itrunAllAsync()
) which does the following:setTimeout
callbacksIn case you're not familiar with
async
methods, they are basically functions that return aPromise
but with some syntactic sugar. The proposed solution would work forasync/await
and promises alike.This would make testing setTimeout with async methods a ton easier, as the above loop could simply be written like this:
The text was updated successfully, but these errors were encountered: