Describe the bug
Using sinon@6.1.0 when I do sinon.useFakeTimers()
- I got an error:
TypeError: Cannot read property 'now' of undefined
at mirrorDateProperties (dist/webpack:/node_modules/sinon/pkg/sinon-esm.js:3644:1)
at hijackMethod (dist/webpack:/node_modules/sinon/pkg/sinon-esm.js:3947:1)
at Object.install (dist/webpack:/node_modules/sinon/pkg/sinon-esm.js:4337:1)
at useFakeTimers (dist/webpack:/node_modules/sinon/pkg/sinon-esm.js:4385:1)
at Sandbox.useFakeTimers (dist/webpack:/node_modules/sinon/pkg/sinon-esm.js:15390:1)
at Context.<anonymous> (dist/webpack:/tests/unit/Countdown.spec.js:23:1)
When I downgrade to sinon@5 - everything is allright!
Context (please complete the following information):
Same problem with [email protected]
:disappointed:
[email protected]
works as expected
A curious phenomenon. I've tried to replicate this using a vanilla Angular project and Sinon 6.1.0, but useFakeTimers() doesn't throw any errors for me, so it might be something in the project environment itself.
From the error message, my guess is this variable becomes undefined somehow.
@moraveyo do you think you can boil this down to a minimal example that shows the issue?
Stack Overflow has a guide on How to create a Minimal, Complete, and Verifiable example
I don't have much time for that now, sorry.
@mroderick I just encountered this issue today. Here is a small repository that replicates the issue: here.
The bug needs both webpack
and jsdom
to show up. The stacktrace and some debugging show the problem arise when lolex
tries to access _global.Date
which doesn't seem set on the window
generated by jsdom
.
@LouisBrunner thank you for creating a runnable test case that is easy to understand 👍
Running the test with test:node
in your repository, it fails as expected.
When I run the test using just mocha
, it passes as expected.
The line that fails is lolex-src.js#L131, just as you concluded with your analysis.
As you concluded, the root cause of this is that the window
object provided by jsdom
does not provide a Date
object. lolex
needs to be able to reference the global scope in order to function correctly, so we cannot make changes and reference Date
directly.
lolex
has support for the JSDOM scenario, check out the lolex.withGlobal
// create a lolex implementation using node's `global`
const lolex = require("lolex").withGlobal(global);
const clock = lolex.install();
setTimeout(fn, 15); // Schedules with clock.setTimeout
clock.uninstall();
We can certainly improve lolex
to throw a descriptive error when its assumptions about the global scope are not met, and suggest that the author uses withGlobal
. Would you like to contribute a pull request for that?
@mroderick Glad the example helped! 😃
I'd be happy to create a PR, however that will only fix lolex
. Is there any way to get sinon.useFakeTimers
to work in this scenario? Maybe by adding an argument like global
to useFakeTimers
that it could use to do call withGlobal
internally?
Is there any new updates about get sinon.useFakeTimers
to work in this scenario. I'm still getting this exception when using mocha in jsDom
Error: The global scope doesn't have a `Date` object (see https://github.com/sinonjs/sinon/issues/1852#issuecomment-419622780)
@LouisBrunner I like that that idea, I think that solution would work for most people 👍
@mroderick I created a PR (#1935) that implement a way to pass the global context through sinon.useFakeTimers
, I don't know if that's the kind of API you had in mind, so feel free to give any feedback!
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.
This has been fixed with #1935
I am using sinon 7.2.7 and when I try to use sinon.useFakeTimers()
I got:
TypeError: Cannot set property performance of #<Window> which has only a getter
The same.
Could be Babel 7? https://github.com/babel/babel/issues/8363
@cichy380 and @axelhunn, please post an issue report. This issue is fixed.
Most helpful comment
@mroderick I created a PR (#1935) that implement a way to pass the global context through
sinon.useFakeTimers
, I don't know if that's the kind of API you had in mind, so feel free to give any feedback!