Javascript 如何使用 sinon 存根 new Date()?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31591098/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 06:52:23  来源:igfitidea点击:

How do I stub new Date() using sinon?

javascripttestingsinonstub

提问by MrHen

I want to verify that various date fields were updated properly but I don't want to mess around with predicting when new Date()was called. How do I stub out the Date constructor?

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

In case it is relevant, these tests are running in a node app and we use TypeScript.

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

回答by Alex Booker

I suspectyou want the useFakeTimersfunction:

怀疑你想要这个useFakeTimers功能:

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

This is plain JS. A working TypeScript/JavaScript example:

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

var now = new Date();

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

afterEach(() => {
    sandbox.restore();
    clock.restore();
});

回答by realplay

sinon.useFakeTimers()was breaking some of my tests for some reason, I had to stub Date.now()

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

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

In that case in the code instead of const now = new Date();you can do

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

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

Or consider option of using momentlibrary for date related stuff. Stubbing moment is easy.

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

回答by Anatoli Klamer

I found this question when i was looking to solution how to mock Dateconstructor ONLY. I wanted to use same date on every test but to avoid mocking setTimeout. Sinon is using lolexinternally Mine solution is to provide object as parameter to sinon:

当我想解决如何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();
})

Other possible parameters you can find in lolexAPI

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