I am not able to stub the moment
constructor when calling it with the format
function to return a pre-defined string, here's an example spec that I would like to run with mocha
:
it('should stub moment', sinon.test(function() {
console.log('Real call:', moment());
const formatForTheStub = 'DD-MM-YYYY [at] HH:mm';
const momentStub = sinon.stub(moment(),'format')
.withArgs(formatForTheStub)
.returns('FOOBARBAZ');
const dateValueAsString = '2025-06-01T00:00:00Z';
const output = moment(dateValueAsString).format(formatForTheStub);
console.log('Stub output:',output);
expect(output).to.equal('FOOBARBAZ');
}));
I am able to see this output using console.log
:
Real call: "1970-01-01T00:00:00.000Z"
Stub output: 01-06-2025 at 01:00
But then the test fails cause 01-06-2025 at 01:00 !== 'FOOBARBAZ'
How can I properly stub that moment(something).format(...)
call?
I found the answer at http://dancork.co.uk/2015/12/07/stubbing-moment/
Apparently moment exposes its prototype using .fn
, so you can:
import { fn as momentProto } from 'moment'
import sinon from 'sinon'
import MyClass from 'my-class'
const sandbox = sinon.createSandbox()
describe('MyClass', () => {
beforeEach(() => {
sandbox.stub(momentProto, 'format')
momentProto.format.withArgs('YYYY').returns(2015)
})
afterEach(() => {
sandbox.restore()
})
/* write some tests */
})
It's hard to tell from the description, but if the reason you are trying to stub the moment constructor(but not the rest of the lib functionality) is because you are trying to control what date Moment returns (for more reliable testing), you can do this using Sinon's usefakeTimer
. Like so:
// Set up context for mocha test.
beforeEach(() => {
this.clock = date => sinon.useFakeTimers(new Date(date));
this.clock('2019-07-07'); // calling moment() will now return July 7th, 2019.
});
You can then update the date in the context of other tests that need to test the inverse logic around a specific date.
it('changes based on the date', () => {
this.clock('2019-09-12');
expect(somethingChanged).to.be.true;
});
Try adding this to your test suite if all else fails;
moment.prototype.format = sinon.stub().callsFake(() => 'FOOBARBAZ');
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With