如何使用sinon存根新的Date()?

MrH*_*Hen 37 javascript testing stub sinon

我想验证各种日期字段是否已正确更新,但我不想乱用预测何时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();
    });
  });
});
Run Code Online (Sandbox Code Playgroud)

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

Ale*_*ker 62

怀疑你想要这个useFakeTimers功能:

var now = new Date();
var clock = sinon.useFakeTimers(now.getTime());
//assertions
clock.restore();
Run Code Online (Sandbox Code Playgroud)

这是简单的JS.一个有效的TypeScript/JavaScript示例:

var now = new Date();

beforeEach(() => {
    sandbox = sinon.sandbox.create();
    clock = sinon.useFakeTimers(now.getTime());
});

afterEach(() => {
    sandbox.restore();
    clock.restore();
});
Run Code Online (Sandbox Code Playgroud)


rea*_*lay 13

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

sinon.stub(Date, 'now').returns(now);
Run Code Online (Sandbox Code Playgroud)

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

const now = new Date(Date.now());
Run Code Online (Sandbox Code Playgroud)

或者考虑使用时刻库来处理与日期相关的内容。存根时刻很容易。


Ana*_*mer 10

当我想解决如何Date仅模拟构造函数时,我发现了这个问题。我想在每次测试中使用相同的日期,但要避免嘲笑setTimeout。Sinon 在内部使用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();
})
Run Code Online (Sandbox Code Playgroud)

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

  • 这个答案令人难以置信,并且展示了有关 sinon/lolex API 的知识。它应该被标记为正确,因为它还解决了测试周围有很多“clock.tick()”的需要。 (2认同)