簡體   English   中英

RSpec 剔除 Date.today 以測試方法

[英]RSpec Stubbing out Date.today in order to test a method

如果當前日期在 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返回我想要的靜態日期,以便我可以測試每個路徑是否正常工作。

  • 如果當前日期在 1 月 1 日至 8 月 1 日之間,我需要測試路徑是否正常工作
  • 如果當前日期在 8 月 1 日之后,我需要測試路徑是否正常工作。

問題:有什么方法可以讓Date.today返回我在規范中構成的值? 在測試return_something_based_on_current_date的規范之后:我希望Date.today的動態實現回到其通常的實現。 我只需要控制Date.today來測試這個方法。

將此添加到您的 before block

allow(Date).to receive(:today).and_return Date.new(2001,2,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

更新

正如安迪在評論中提到的,自 Rails 4.1 以來,有一個輔助方法travel_to可用

可在此處獲得參考: http : //api.rubyonrails.org/classes/ActiveSupport/Testing/TimeHelpers.html

您可能需要考慮另一種方法,它不需要任何存根——更改公共方法以接受當前日期的參數。

澄清:

更改def return_something_based_on_current_datedef return_something_based_on_current_date(current_date)然后更改的所有實例Date.todaycurrent_date 您還需要將current_date傳遞給私有方法。

然后在你的測試中,你可以通過任何你想要的作為current_date

我處於類似的情況,但我不想安裝 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

所以我只是測試了預期日期,我擔心一天中會有特定時間測試會被破壞但我不在乎

從 Rails 4.2 開始, ActiveSupport::Testing::TimeHelpers模塊提供了一種簡單的方法來做到這一點:

travel_to(Time.parse("2019-01-19")) do
  # your code here
end

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM