Reputation: 2362
I have the following code:
def when_to_change
year, month = Date.today.strftime("%Y %m").split(' ').map {|v| v.to_i}
if month < 9
year + 2
else
year + 3
end
end
And I try to stub it in my spec in the following way:
it 'when current month at the of a year' do
allow(Date.today).to receive(:strftime).with('%Y %m').and_return('2015 10')
expect(@car.when_to_change).to eq(2018)
end
it 'when current month earlier than september' do
allow(Date.today).to receive(:strftime).with('%Y %m').and_return('2015 07')
expect(@car.when_to_change).to eq(2017)
end
When I try to run specs it doesn't look that way. What am I doing wrong?
I use rspec v3.3.2
ANSWER
Since Date.today
returns new object every method call, this can be done in the following way:
it 'when current month earlier than september' do
allow(Date).to receive(:today).and_return(Date.new(2015, 7, 19))
expect(@car.when_to_change).to eq(2017)
end
thank you to @DmitrySokurenko for explanation.
Upvotes: 0
Views: 1677
Reputation: 2493
You don't need Timecop to do that. Rails already has a similar thing built-in:
http://api.rubyonrails.org/classes/ActiveSupport/Testing/TimeHelpers.html
# spec/rails_helper.rb
config.include ActiveSupport::Testing::TimeHelpers
And then:
travel_to(Date.parse('2015-10-01')) do
expect(@car.when_to_change).to eq(2018)
end
Upvotes: 1
Reputation: 6132
Date.today
always return new objects. Stub the today
at first.
I mean that:
>> Date.today.object_id
=> 70175652485620
>> Date.today.object_id
=> 70175652610440
So when you call the today
next time, that's a different object.
Thus either stub the Date.today
to return some fixed date, either change your code to use something like SomeHelper.today
which will always return the same date in test environment.
Upvotes: 1