MrHen
MrHen

Reputation: 2480

How do I stub new Date() using sinon?

I want to verify that various date fields were updated properly but I don't want to mess around with predicting when new Date() was called. How do I stub out the Date constructor?

import sinon = require('sinon');
import should = require('should');

describe('tests', () => {
  var sandbox;
  var now = new Date();

  beforeEach(() => {
    sandbox = sinon.sandbox.create();
  });

  afterEach(() => {
    sandbox.restore();
  });

  var now = new Date();

  it('sets create_date', done => {
    sandbox.stub(Date).returns(now); // does not work

    Widget.create((err, widget) => {
      should.not.exist(err);
      should.exist(widget);
      widget.create_date.should.eql(now);

      done();
    });
  });
});

In case it is relevant, these tests are running in a node app and we use TypeScript.

Upvotes: 65

Views: 50243

Answers (3)

Anatoli Klamer
Anatoli Klamer

Reputation: 2638

I found this question when i was looking to solution how to mock Date constructor ONLY. I wanted to use same date on every test but to avoid mocking setTimeout. Sinon is using [lolex][1] internally Mine solution is to provide object as parameter to sinon:

let clock;

before(() => {
    clock = sinon.useFakeTimers({
        now: new Date(2019, 1, 1, 0, 0),
        shouldAdvanceTime: true,
        toFake: ["Date"],
    });
})

after(() => {
    clock.restore();
})

Other possible parameters you can find in [lolex][1] API [1]: https://github.com/sinonjs/lolex#api-reference

Upvotes: 26

realplay
realplay

Reputation: 2325

sinon.useFakeTimers() was breaking some of my tests for some reason, I had to stub Date.now()

sinon.stub(Date, 'now').returns(now);

In that case in the code instead of const now = new Date(); you can do

const now = new Date(Date.now());

Or consider option of using moment library for date related stuff. Stubbing moment is easy.

Upvotes: 20

Alex Booker
Alex Booker

Reputation: 10777

I suspect you want the useFakeTimers function:

var now = new Date();
var clock = sinon.useFakeTimers(now.getTime());
//assertions
clock.restore();

This is plain JS. A working TypeScript/JavaScript example:

var now = new Date();

beforeEach(() => {
    sandbox = sinon.sandbox.create();
    clock = sinon.useFakeTimers(now.getTime());
});

afterEach(() => {
    sandbox.restore();
    clock.restore();
});

Upvotes: 100

Related Questions