[rspec-users] stubbing Time.zone.now for model tests fails for Rails 2.3.1

David Schmidt davids at tower-mt.com
Wed Mar 11 13:40:07 EDT 2009


Our application has some code to schedule recurring tasks, with code  
to skip holidays and weekends.

In order to test the schedule model we need to have a fixed time  
returned when the model is run so that the tests will run the same no  
matter what day they are run.  (The first set of tests written would  
all pass until run on a weekend, when the skip code would schedule a  
task days later in order to skip a weekend day.)

Our solution under Rails 2.1 was to set an instance variable to a  
fixed time and then to stub the time returned, similar to the method  
that David Chelimsky recommended:

now = Time.now
Time.stub!(:now).and_return(now)

However, our app is using Time.zone.now in order to return local time  
in the user's local time zone.  The following code works in Rails 2.1:

@now = Time.now
@timezone = TimeZone.new('UTC')
Time.stub!(:zone).and_return(@timezone)
@timezone.stub!(:now).and_return(@new)

In Rails 2.1 this properly returned @now when the model accessed  
Time.zone.now.

After upgrading to Rails 2.3.1 (and RSpec 1.1.99.12) *all* tests that  
use this method fail.  They appear to fail as soon as a time from  
Time.zone.now is saved to a model and then accessed, even though the  
time in the record appears fine.

The error we're getting is:

"You have a nil object when you didn't expect it!
The error occurred while evaluating nil.period_for_utc"

If I comment out the last two lines above ("Time.stub!" and  
"@timezone.stub!") then I don't get that error, but without fixed  
times some of our tests fail due to the variable time.

Has anyone else run into this problem and come up with a solution to  
getting a fixed time back from Time.zone.now?

David Schmidt
davids at tower-mt.com


More information about the rspec-users mailing list