【问题标题】:Stubbing Time.now with RSpec使用 RSpec 存根 Time.now
【发布时间】:2015-08-30 19:42:44
【问题描述】:

我正在尝试按如下方式在 RSpec 中存根 Time.now:

it "should set the date to the current date" do
    @time_now = Time.now
    Time.stub!(:now).and_return(@time_now)

    @thing.capture_item("description")
    expect(@thing.items[0].date_captured).to eq(@time_now)
end

这样做时出现以下错误:

 Failure/Error: Time.stub!(:now).and_return(@time_now)
 NoMethodError:
   undefined method `stub!' for Time:Class

知道为什么会发生这种情况吗?

【问题讨论】:

  • 正如它所说的那样。 Time 没有名为 stub! 的方法。

标签: ruby rspec


【解决方案1】:

来自ActiveSupporttravel_to 可能更好地服务于目的,可能如下所示:

def test_date
  travel_to Time.zone.parse('1970-01-01')
  verify
  travel_back
end

【讨论】:

    【解决方案2】:

    根据您的 RSpec 版本,您可能希望使用较新的语法:

    allow(Time).to receive(:now).and_return(@time_now)
    

    RSpec Mocks 3.3

    【讨论】:

    • 值得指出的是,这条线必须在'before'块中才能工作。当我在“it”块内测试它时,它没有任何效果。
    • 如何模拟DateTime.now.in_time_zone?我需要在每月的第一天,星期一,0 小时运行测试。
    【解决方案3】:

    您可以使用timecop。测试前冻结时间,测试后解冻。

    describe "some tests" do
      before do
        Timecop.freeze(Time.now)
      end
    
      after do
        Timecop.return
      end
    
      it "should do something" do
      end
    end
    

    或者用

    定义一个具体的时间
    let(:time_now) { Time.now }
    

    并在Timecop.freeze(time_now) 和测试中使用

    【讨论】:

      【解决方案4】:

      您可以随时使用timecop:

      @time_now = Time.now
      
      Timecop.freeze(@time_now) do
        @thing.capture_item("description")
        expect(@thing.items[0].date_captured).to eq(@time_now)
      end
      

      【讨论】:

      • 或带有前块:before { Timecop.freeze(Time.now) }
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-29
      • 1970-01-01
      • 1970-01-01
      • 2014-04-11
      • 1970-01-01
      相关资源
      最近更新 更多