Reputation: 2480
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
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
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
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