[rspec-users] Stubbing times: #from_now et al.

Ben Mabey ben at benmabey.com
Wed Nov 5 15:02:29 EST 2008

Nick Hoffman wrote:
> I had a look around for how to stub Time.now , #from_now , etc, and 
> came across this, which was useful:
> http://devblog.michaelgalero.com/2007/11/23/actioncontroller-rspec-stub-timenow/ 
> Unfortunately, my situation is slightly different, and causes that 
> solution to not be applicable. This is what I'm trying to spec:
> def remember_me_for(time)
>   remember_me_until time.from_now.utc
> end
> I thought this would work:
> it 'should remember a user for a period of time' do
>   user          = create_user
>   one_week      = 1.week
>   from_now      = 1.week.from_now
>   from_now_utc  = 1.week.from_now.utc
>   one_week.stub!(:from_now).and_return from_now
>   from_now.stub!(:utc).and_return from_now_utc
>   user.should_receive(:remember_me_until).with from_now_utc
>   user.remember_me_for one_week
> end
> But that fails, referencing the stub on "one_week":
> TypeError in 'User should remember a user for a period of time'
> no virtual class for Fixnum
> Any suggestions for how to solve this? Thanks!
> Nick
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users

Hey Nick,
It is generally a bad idea to stub/mock a method on the object you are 
verifying the behaviour of. I would recommend a state-based approach of 
testing this method as opposed to the interaction-based one you are 
pursuing.  The reason being is that you want to verify the behaviour of 
the object as a whole.  How the object uses it's internal methods and 
state is none of the code example's business.  Without knowing the other 
methods on User I don't know the best way to verify the behavior.. What 
other methods that deal with the remember functionality are part of the 
public API?  Assuming it is an AR model and you have a 
'remember_me_until' column you could do something like:

it 'should remember a user for a period of time' do
  user          = create_user
  user.remember_me_until.should == 1.week.from_now.utc

Again, using the #remember_me_until method is testing the internal state 
of the object but without knowing your other methods I don't what the 
better options (if any) are.


More information about the rspec-users mailing list