SuperManEver
SuperManEver

Reputation: 2362

How to stub Date.today.strftime in rspec 3?

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

Answers (3)

Marcin Urbanski
Marcin Urbanski

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

Andrey Deineko
Andrey Deineko

Reputation: 52357

I think timecop would be exactly what you need.

Upvotes: 3

Dmitry Sokurenko
Dmitry Sokurenko

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

Related Questions