如何存根 Time.now.hour

How to stub Time.now.hour

我有一个辅助方法,它在等待时间的视图中输出问候语 #{greet(Time.now.hour)}

users_helper.rb:

def greet(hour_of_clock)
 if hour_of_clock >= 1 && hour_of_clock <= 11
  "Morning"
 elsif hour_of_clock >= 12 && hour_of_clock <= 16
  "Afternoon"
 else
  "Evening"
 end
end

我正在尝试如下测试失败:

users_feature_spec.rb

describe 'greeting a newly registered user' do
  before do 
    @fake_time = Time.parse("11:00")
    Time.stub(:now) { @fake_time }
  end
  it 'tailors the greeting to the time of day' do
    visit '/'
    fill_in 'Name here...', with: 'test name'
    fill_in 'Your email here...', with: 'test@test.com'
    click_button 'Notify me'

    expect(page).to have_content 'Morning'
  end
end

测试失败,因为 Time.now.hour 没有像上面预期的那样被存根。

由于各种建议,我现在已经尝试了各种变体,至少在语法上看起来是正确的两个主要重新格式是:

describe 'greeting a newly registered user' do
  before do 
    @fake_time =  Time.parse("11:00")
    allow(Time).to receive(:now).and_return(@fake_time)  
  end
  it 'tailors the greeting to the time of day' do
      visit '/'
      fill_in 'Name here...', with: 'test name'
      fill_in 'Your email here...', with: 'test@test.com'
      click_button 'Notify me'

      expect(page).to have_content 'Morning'
    end
  end

并使用新的ActiveSupport::Testing::TimeHelpers方法#travel_to:

describe 'greeting a newly registered user' do
  it 'tailors the greeting to the time of day' do
    travel_to Time.new(2013, 11, 24, 01, 04, 44) do
      visit '/'
      fill_in 'Name here...', with: 'test name'
      fill_in 'Your email here...', with: 'test@test.com'
      click_button 'Notify me'

      expect(page).to have_content 'Morning'
    end
  end

但我仍然做错了,这意味着 #greet 仍在获取 Time.now.hour 的实时输出,而不是使用我的存根或 travel_to 时间值。有什么帮助吗?

你可以试试这个:

let!(:fake_hour) { '11' }
before do 
  allow(Time).to receive_message_chain(:now, :hour).and_return(fake_hour)
end

另一种方法是使用 Timecop (or the new Rails replacement travel_to) 为您打发时间。使用 Timecop,您可以获得超级可读的规格,无需手动存根:

# spec setup

Timecop.freeze(Time.now.beginning_of_day + 11.hours) do
  visit root_path
  do_other_stuff!
end

我放弃了自己尝试或使用 ::TimeHelpers 方法 #travel_to :( 并使用了 Timecop gem,第一次工作如下:

before do 
    Timecop.freeze(Time.now.beginning_of_day + 11.hours)
end

it 'tailors the greeting to the time of day' do
    visit '/'
    fill_in 'Name here...', with: 'test name'
    fill_in 'Your email here...', with: 'test@test.com'
    click_button 'Notify me'

    expect(page).to have_content 'Morning'
end

不过,我真的很想知道我原来的方法出了什么问题,有人看到出了什么问题吗?