与Sinon一起使用stub moment.js构造函数

问题描述 投票:11回答:2

当使用moment函数调用format构造函数来返回预定义的字符串时,我无法对其进行存根,这是我想用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');

}));

我能够使用console.log看到这个输出:

Real call: "1970-01-01T00:00:00.000Z"
Stub output: 01-06-2025 at 01:00

但随后测试失败导致01-06-2025 at 01:00 !== 'FOOBARBAZ'我怎样才能正确存根moment(something).format(...)呼叫?

mocha momentjs sinon chai
2个回答
18
投票

我在http://dancork.co.uk/2015/12/07/stubbing-moment/找到了答案

显然,时刻会使用.fn暴露其原型,因此您可以:

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

})

3
投票

从描述中很难说清楚,但是如果你试图将时刻构造函数(而不是lib函数的其余部分)存在的原因是因为你试图控制Moment返回的日期(为了更可靠的测试),你可以使用Sinon的usefakeTimer做到这一点。像这样:

// 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.
      });

然后,您可以在需要测试特定日期周围的反逻辑的其他测试的上下文中更新日期。

it('changes based on the date', () => {
  this.clock('2019-09-12');
  expect(somethingChanged).to.be.true;
});
© www.soinside.com 2019 - 2024. All rights reserved.