Sinon: "TypeError: Cannot read property 'now' of undefined" when sinon.useFakeTimers()

Created on 5 Jul 2018  ·  15Comments  ·  Source: sinonjs/sinon

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!

My repo:
https://github.com/moraveyo/chess-clock/blob/bf764f3ed9026366de9375bbc870109e4f007099/tests/unit/Countdown.spec.js#L23

Context (please complete the following information):

  • Library version: 6.1.0
  • Environment: Ubuntu 16.04
  • Example URL:
  • Other libraries you are using:

    • "vue": "^2.5.16",

    • "vue-router": "^3.0.1"

    • "@vue/cli-plugin-babel": "^3.0.0-beta.15",

    • "@vue/cli-plugin-eslint": "^3.0.0-beta.15",

    • "@vue/cli-plugin-unit-mocha": "^3.0.0-beta.15",

    • "@vue/cli-service": "^3.0.0-beta.15",

    • "@vue/eslint-config-airbnb": "^3.0.0-rc.3",

    • "@vue/test-utils": "^1.0.0-beta.16",

    • "chai": "^4.1.2",

    • "vue-template-compiler": "^2.5.16"

    • Mocha 5.2.0

    • Webpack 4.15.1

Help wanted stale

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!

All 15 comments

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.

Was this page helpful?
0 / 5 - 0 ratings