如果当前日期在1月1日到8月1日之间,我想测试一个跟随一条路径的方法,或者如果当前日期介于当前日期之后,我想测试另一条路径8月2日 - 12月31日。例如:
def return_something_based_on_current_date
if date_between_jan_1_and_aug_1?
return "foo"
else
return "bar"
end
end
private
def date_between_jan_1_and_aug_1?
date_range = build_date_range_jan_1_through_aug_1
date_range === Date.today
end
def build_date_range_jan_1_through_aug_1
Date.today.beginning_of_year..Date.new(Date.today.year, 8, 1)
end
正如您所看到的那样:return_something_based_on_current_date
在很大程度上取决于Date.today
,它调用的私有方法也是如此。由于Date.today
动态返回当前日期,因此很难在此方法中测试这两个路径。
出于测试目的:我需要Date.today
返回我想要的静态日期,以便我可以测试每条路径是否正常工作。
问题:有没有办法让Date.today
返回我在规格范围内组成的值?在测试return_something_based_on_current_date
的规范之后:我希望Date.today
的动态实现回到其通常的实现。我只需要控制Date.today
来测试这种方法。
答案 0 :(得分:7)
将此内容添加到block
之前。
allow(Date).to receive(:today).and_return Date.new(2001,2,3)
我认为*没有必要取消存储。
答案 1 :(得分:3)
我建议您查看Timecop gem,它允许冻结给定日期的时间。
除了存在当前时间之外,它还允许在给定测试的时间内传播
https://github.com/travisjeffery/timecop
describe "some set of tests to mock" do
before do
Timecop.freeze(Time.local(1990))
end
after do
Timecop.return
end
it "should do blah blah blah" do
end
end
<强>更新强>
正如Andy在评论中提到的,自Rails 4.1以来有一种帮助方法travel_to
参考资料如下: http://api.rubyonrails.org/classes/ActiveSupport/Testing/TimeHelpers.html
答案 2 :(得分:0)
您可能需要考虑另一种方法,即不需要任何存根 - 更改公共方法以接受当前日期的参数。
澄清:
将def return_something_based_on_current_date
更改为def return_something_based_on_current_date(current_date)
,然后将Date.today
的所有实例更改为current_date
。您还需要将current_date
传递给私有方法。
然后在您的测试中,您可以将所需的任何内容传递给current_date
。
答案 3 :(得分:0)
我处于类似情况,但我不想安装gem。因为我对大于一天的时间间隔感兴趣,所以我决定采用这种方式
it 'Creates an event for tomorrow' do
event = FactoryBot.create(:event, :tomorrow)
expect(event.date.day).to eq (Time.now + 1.day).day
end
it 'Creates an event for the next week' do
event = FactoryBot.create(:event, :next_week)
expect(event.date.day).to eq (Time.now + 1.week).day
end
it 'Creates an event for the next month' do
event = FactoryBot.create(:event, :next_month)
expect(event.date.day).to eq (Time.now + 1.month).day
end
所以我只是测试了预期的日期,所以恐怕一天中的某个特定时间测试会被破坏,但我不在乎
答案 4 :(得分:0)
从Rails 4.2开始,ActiveSupport::Testing::TimeHelpers
模块提供了一种简单的方法:
travel_to(Time.parse("2019-01-19")) do
# your code here
end