Stubbing Time.now with RSpec
Depending on your version of RSpec you might want to use the newer syntax:
allow(Time).to receive(:now).and_return(@time_now)
See RSpec Mocks 3.3
How to stub Time.now.hour
Another approach would be to use Timecop (or the new Rails replacement travel_to
) to stub out your time for you. With Timecop you can have super readable specs with no need for manual stubbing:
# spec setup
Timecop.freeze(Time.now.beginning_of_day + 11.hours) do
visit root_path
do_other_stuff!
end
RSpec Stubbing out Date.today in order to test a method
Add this to your before block
.
allow(Date).to receive(:today).and_return Date.new(2001,2,3)
I *think* it is not necessary to unstub.
What is the best way to stub date in spec?
You can use Timecop:
It provides very simple way to freeze
time at any point you want, for example:
describe "#sales_by_week" do
before { Timecop.freeze(Time.now.beginning_of_week+6.days) }
it "returns the number of sale by week" do
create(:sale, created_at: 2.weeks.ago)
create(:sale, created_at: 3.days.ago)
create(:sale, created_at: Date.today )
res = subject.sales_by_week
expect(res.values.last).to eq(2)
end
end
How to stub out Date that is implicitly referenced by years.ago in RSpec?
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
How to stub Date.today.strftime in rspec 3?
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.
Stubbing tomorrow's date in rspec
The issue is that the times might look exactly the same, but the timestamps aren't, the time which is spent between running the two statements ( even if it's in micro seconds ) makes the time different, to solve it you should use the same time variable in both statements, for example:
time = Time.now
S3Client.should_receive(:upload_csv_by_path).with("#{Rails.root}/tmp/scalar_test_exporter.csv", nil, expires: time)
S3Client.upload_csv_by_path(file_name, nil, expires: time)
This way you could make sure that the time is the same in both statements, or you could use a gem like timecop to help you with this like @gotva suggested, timecop is very useful because it gives you the ability to freeze time, move forward and backwards in time, it's nice, for the same example you'd write this
Time.freeze
S3Client.should_receive(:upload_csv_by_path).with("#{Rails.root}/tmp/scalar_test_exporter.csv", nil, expires: 1.day.from_now)
S3Client.upload_csv_by_path(file_name, nil, expires: 1.day.from_now)
Time.return
Setting system time in rspec tests without changing system clock
before {Time.stub(:now) {Time.now.utc}}
With this, anywhere Time.now
is called in your tests, it will return your system's time in UTC.
Example:
describe Time do
before {Time.stub(:now) {Time.now.utc}}
it "returns utc as my system's time" do
Time.now.utc?.should be_true
end
end
Related Topics
Constants or Class Variables in Ruby
How to Iterate Through an Array Starting from the Last Element? (Ruby)
How to Force One Field in Ruby's CSV Output to Be Wrapped with Double-Quotes
How to Use Rspec Expectations in Irb
Using the Value of a Variable as Another Variables Name in Ruby
How to Update Gems in Ruby for Windows
Spork 0.9.2 and Rspec 3.0.0 = Uninitialized Constant Rspec::Core::Commandline (Nameerror)
No Such File to Load Bundler Error for Rails 3
Differencebetween "Be_True" and "Be True" in Rspec
Natural Language Date Parser for Ruby/Rails
Ruby Equivalent of Perl Data::Dumper
How to Check If There's a Nil Set or Not in an Array
Escape Double and Single Backslashes in a String in Ruby
Ruby: Creating a Hash Key and Value from a Variable in Ruby
How Would I Go About Programmatically Interacting with VSt(I) Plugins to Synthesize Audio
How to Prevent Pipe Character from Causing a Bad Uri Error in Rails 3/Ruby 1.9.2