如何在 rspec 3 中存根 Date.today.strftime?
How to stub Date.today.strftime in rspec 3?
我有以下代码:
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
我尝试通过以下方式将其存入我的规范中:
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
当我尝试 运行 规格时,它看起来不是那样的。我做错了什么?
我用rspecv3.3.2
ANSWER
因为 Date.today
returns 每次方法调用都会新建一个对象,这可以通过以下方式完成:
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
感谢@DmitrySokurenko 的解释。
Date.today
总是 return 个新对象。首先存根 today
。
我的意思是:
>> Date.today.object_id
=> 70175652485620
>> Date.today.object_id
=> 70175652610440
因此,当您下次调用 today
时,那是一个不同的对象。
因此,要么将 Date.today
存根到 return 某个固定日期,要么更改您的代码以使用类似 SomeHelper.today
的内容,这将始终 return 在测试中使用相同的日期环境。
我认为 timecop 正是您所需要的。
你不需要 Timecop 来做那件事。 Rails 已经内置了类似的东西:
http://api.rubyonrails.org/classes/ActiveSupport/Testing/TimeHelpers.html
# spec/rails_helper.rb
config.include ActiveSupport::Testing::TimeHelpers
然后:
travel_to(Date.parse('2015-10-01')) do
expect(@car.when_to_change).to eq(2018)
end
我有以下代码:
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
我尝试通过以下方式将其存入我的规范中:
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
当我尝试 运行 规格时,它看起来不是那样的。我做错了什么?
我用rspecv3.3.2
ANSWER
因为 Date.today
returns 每次方法调用都会新建一个对象,这可以通过以下方式完成:
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
感谢@DmitrySokurenko 的解释。
Date.today
总是 return 个新对象。首先存根 today
。
我的意思是:
>> Date.today.object_id
=> 70175652485620
>> Date.today.object_id
=> 70175652610440
因此,当您下次调用 today
时,那是一个不同的对象。
因此,要么将 Date.today
存根到 return 某个固定日期,要么更改您的代码以使用类似 SomeHelper.today
的内容,这将始终 return 在测试中使用相同的日期环境。
我认为 timecop 正是您所需要的。
你不需要 Timecop 来做那件事。 Rails 已经内置了类似的东西:
http://api.rubyonrails.org/classes/ActiveSupport/Testing/TimeHelpers.html
# spec/rails_helper.rb
config.include ActiveSupport::Testing::TimeHelpers
然后:
travel_to(Date.parse('2015-10-01')) do
expect(@car.when_to_change).to eq(2018)
end