Stub moment.js constructor with Sinon

TPPZ picture TPPZ · Feb 11, 2016 · Viewed 10.3k times · Source

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?

Answer

IanVS picture IanVS · May 17, 2016

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 */

})