【问题标题】:How do I stub new Date() using sinon?如何使用 sinon 存根 new Date()?
【发布时间】:2015-10-13 23:30:08
【问题描述】:

我想验证各种日期字段是否已正确更新,但我不想预测何时调用 new Date()。如何存根 Date 构造函数?

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();
    });
  });
});

如果相关,这些测试在节点应用程序中运行,我们使用 TypeScript。

【问题讨论】:

    标签: javascript testing sinon stub


    【解决方案1】:

    怀疑你想要useFakeTimers函数:

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

    这是纯 JS。一个有效的 TypeScript/JavaScript 示例:

    var now = new Date();
    
    beforeEach(() => {
        sandbox = sinon.sandbox.create();
        clock = sinon.useFakeTimers(now.getTime());
    });
    
    afterEach(() => {
        sandbox.restore();
        clock.restore();
    });
    

    【讨论】:

    • 太棒了,看起来它可以满足我的需求。一旦我得到一个最终工作的版本,我会把它编辑成你的答案并接受它。
    • 从 sinon v5 开始,sinon 对象是一个跟踪 sinon.useFakeTimers 的沙箱,可以用 sinon.restore() 调用,允许 sandboxclock 变量在以上要删除:sinonjs.org/guides/…
    • 这里只是一个小观察:当你使用沙盒时(你应该这样做),你不需要clock.restore(),因为沙盒会处理它
    【解决方案2】:

    sinon.useFakeTimers() 出于某种原因破坏了我的一些测试,我不得不存根 Date.now()

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

    在这种情况下,在代码中而不是 const now = new Date(); 你可以这样做

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

    或者考虑使用moment 库来获取与日期相关的内容。存根很容易。

    【讨论】:

    • 这对我有用,除了Date.now() 返回一个时间戳,所以我认为now 方法应该使用Date.now() 返回的时间戳进行存根,而不是使用new Date() 创建一个新日期.基本上第二行应该是:const now = Date.now();
    【解决方案3】:

    我在寻找解决方案时发现了这个问题,如何仅模拟 Date 构造函数。 我想在每次测试中使用相同的日期,但要避免嘲笑 setTimeout。 诗乃在内部使用lolex 我的解决方案是将对象作为参数提供给 sinon:

    let clock;
    
    before(async function () {
        clock = sinon.useFakeTimers({
            now: new Date(2019, 1, 1, 0, 0),
            shouldAdvanceTime: true,
            advanceTimeDelta: 20
        });
    })
    
    after(function () {
        clock.restore();
    })
    

    您可以在lolex API 中找到其他可能的参数

    【讨论】:

    • 这个答案令人难以置信,展示了有关 sinon/lolex API 的知识。它应该被标记为正确,因为它还解决了在测试中需要大量clock.tick()s。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-18
    • 1970-01-01
    • 1970-01-01
    • 2018-10-15
    • 2017-05-04
    • 1970-01-01
    相关资源
    最近更新 更多