Время обрушения. Теперь с RSpec

Я пытаюсь заглушить Time.now в RSpec следующим образом:

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

Любая идея, почему это может произойти?

Ответ 1

В зависимости от вашей версии RSpec вы можете использовать новый синтаксис:

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

См. RSpec Mocks 3.3

Ответ 2

Вы всегда можете использовать 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

Ответ 3

travel_to из ActiveSupport может лучше служить цели и может выглядеть следующим образом:

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

Ответ 4

Вы можете использовать таймкоп. Заморозьте время до теста и разморозьте его после.

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) и в тестах