Reputation: 5178
I know that I can stub out a method on Date
like so:
allow(Date).to receive(:today).and_return Date.new(2015,11,10)
So now if within my spec the code calls Date.today
I can be assured that it will return a Date object with the value of 11/10/2015.
I have a scope that utilizes years.ago.to_date
. The user specifies the number of years ago for the scope: Ex: 5.years.ago
, 2.years.ago
.
I am trying to test this scope. In order to do so I need to control the Date
that years.ago
is referencing. For instance, I would always want the Date to be 1/1/2010. This way I will know that 5.years.ago
will return 1/1/2005, and 2.years.ago would return 1/1/2008.
The issue is that I do not know what to stub out. I do not know how to keep the Date consistent which years.ago
uses.
Hopefully this makes sense. I just need to control the Date that years.ago
uses. How can I stub that out?
I looked a bit at ActiveSupport::Duration, but I'm not sure if that is the right place to look.
Upvotes: 1
Views: 758
Reputation: 37627
You can usually control what Ruby and Rails use for the current time by stubbing Time.now
:
allow(Time).to receive(:now).and_return(Time.local 2016, 9, 6, 16, 51)
That does work for years.ago
.
If your code, or the framework code you use, uses both Time.now
and Date.today
, however, timecop is easier.
If you use timecop, be aware that it's easy to forget to Timecop.return
, which can screw up subsequent tests. Prefer timecop's safe mode.
Upvotes: 1
Reputation: 6438
You should check timecop
Then in your tests, you could freeze the date
to your desired value as follows:
describe "some set of tests to mock" do
before do
Timecop.freeze(2010, 1, 1)
end
after do
Timecop.return
end
it "should do blah blah blah" do
end
end
Upvotes: 4