Stpecbing Time.now与RSpec

Pat*_*ngo 21 ruby rspec

我试图在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
Run Code Online (Sandbox Code Playgroud)

这样做时我收到以下错误:

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

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

spi*_*ann 44

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

allow(Time).to receive(:now).and_return(@time_now)
Run Code Online (Sandbox Code Playgroud)

RSpec Mocks 3.3

  • 值得指出的是,这条线必须在'之前'块中才能工作.当我在'it'区块内测试它时,它没有任何效果. (3认同)

Art*_*jev 7

travel_tofromActiveSupport可能更好地达到目的,可能如下所示:

def test_date
  travel_to Time.zone.parse('1970-01-01')
  verify
  travel_back
end
Run Code Online (Sandbox Code Playgroud)


Ped*_*nto 5

您可以随时使用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
Run Code Online (Sandbox Code Playgroud)


mms*_*viu 5

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

describe "some tests" do
  before do
    Timecop.freeze(Time.now)
  end

  after do
    Timecop.return
  end

  it "should do something" do
  end
end
Run Code Online (Sandbox Code Playgroud)

或定义一个特定的时间

let(:time_now) { Time.now }
Run Code Online (Sandbox Code Playgroud)

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