Reputation: 2200
I have a helper method which outputs a greeting #{greet(Time.now.hour)}
in the view pending the time of day:
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
And I am trying to test this unsuccessfully as below:
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: '[email protected]'
click_button 'Notify me'
expect(page).to have_content 'Morning'
end
end
The test fails as the Time.now.hour is not being stubbed as intended above.
I've now tried all sorts of variations thanks to various advice, the two main reformats which it at least seemed were syntactically correct were:
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: '[email protected]'
click_button 'Notify me'
expect(page).to have_content 'Morning'
end
end
and using the new ActiveSupport::Testing::TimeHelpers method #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: '[email protected]'
click_button 'Notify me'
expect(page).to have_content 'Morning'
end
end
But still I'm doing something wrong which means that #greet
is still taking the live output of Time.now.hour
and not using my stubbed or travel_to Time value. Any help please?
Upvotes: 2
Views: 2936
Reputation: 2200
I gave up trying to either stub out myself or use the ::TimeHelpers
method #travel_to
:( and used the Timecop gem, worked first time as below:
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: '[email protected]'
click_button 'Notify me'
expect(page).to have_content 'Morning'
end
I would really like to understand what was failing with my original approach though, does anyone see what was going wrong?
Upvotes: 0
Reputation: 7405
You can try this :
let!(:fake_hour) { '11' }
before do
allow(Time).to receive_message_chain(:now, :hour).and_return(fake_hour)
end
Upvotes: 2
Reputation: 4813
Another approach would be to use Timecop (or the new Rails replacement travel_to
) to stub out your time for you. With Timecop you can have super readable specs with no need for manual stubbing:
# spec setup
Timecop.freeze(Time.now.beginning_of_day + 11.hours) do
visit root_path
do_other_stuff!
end
Upvotes: 1