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
On Wed, Nov 5, 2008 at 12:51 PM, Nick Hoffman <nick at deadorange.com> 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!Looks like you can''t stub anything on a Fixnum because of the way RSpec''s mocking works.>> require ''spec/mocks''=> true>> 1.stub!(:foo)TypeError: no virtual class for Fixnum Same with mocha, apparently.>> require ''mocha''=> true>> 1.stubs(:foo)TypeError: no virtual class for Fixnum Same with rr:>> require ''rr''=> true>> mock(1).fooTypeError: no virtual class for Fixnum And lastly (but not leastly), flexmock:>> require ''flexmock'' >> include FlexMock::MockContainer=> Object>> flexmock(1).fooTypeError: no virtual class for Fixnum The problem is there is no Singleton Class for 1, probably an efficiency in Ruby since 1 is, itself, a Singleton. All of these frameworks try to manipulate methods on the object''s singleton class. So no mocking/stubbing on Fixnums. Apparently. Not much help - sorry. David> Nick
On 2008-11-05, at 14:42, David Chelimsky wrote:> The problem is there is no Singleton Class for 1, probably an > efficiency in Ruby since 1 is, itself, a Singleton. > > All of these frameworks try to manipulate methods on the object''s > singleton class. So no mocking/stubbing on Fixnums. Apparently. > > Not much help - sorry.That was a good explanation. Thanks, mate. At least now I know not to chase this path any further!
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-usersHey 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_for(1.week) user.remember_me_until.should == 1.week.from_now.utc end 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. HTH, Ben
On Wed, Nov 5, 2008 at 11:42 AM, David Chelimsky <dchelimsky at gmail.com>wrote:> Looks like you can''t stub anything on a Fixnum because of the way > RSpec''s mocking works. > > >> require ''spec/mocks'' > => true > >> 1.stub!(:foo) > TypeError: no virtual class for Fixnum >What I can''t figure out is this:>> 1.day=> 1 day>> 1.day.class=> Fixnum Is 1.day an ActiveSupport::Duration or a Fixnum? ///ark -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20081105/3106139e/attachment.html>
On 2008-11-05, at 15:02, Ben Mabey wrote:> 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_for(1.week) > user.remember_me_until.should == 1.week.from_now.utc > end > > 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. > > HTH, > BenHi Ben. #remember_me is used to keep a user logged in to the website if they ticked the "Remember me?" checkbox in the login form. It''s only called from one location in the app: case when valid_remember_cookie? then @current_user.refresh_token # keeping same expiry date when new_cookie_flag then @current_user.remember_me else @current_user.forget_me end So as you suggested, my spec example should probably just be checking to see that the User instance''s "remember_me_until" attribute is set to an appropriate value. Thanks! Nick
On 2008-11-05, at 15:10, Mark Wilden wrote:> What I can''t figure out is this: > > >> 1.day > => 1 day > > >> 1.day.class > => Fixnum > > Is 1.day an ActiveSupport::Duration or a Fixnum? > > ///arkIt''s an ActiveSupport::Duration : 48 def days 49 ActiveSupport::Duration.new(self * 24.hours, [[:days, self]]) 50 end 51 alias :day :days I''ve no idea why 1.day.class returns Fixnum though..
On Wed, Nov 5, 2008 at 12:26 PM, Nick Hoffman <nick at deadorange.com> wrote:> On 2008-11-05, at 15:10, Mark Wilden wrote: > >> What I can''t figure out is this: >> >> >> 1.day >> => 1 day >> >> >> 1.day.class >> => Fixnum >> >> I''ve no idea why 1.day.class returns Fixnum though.. >Yeah, I''d looked at the code. Why #class returns Fixnum was my question, actually. Something to do with coercion, maybe. The other thing is that if it were simply a Duration, I''d expect you to be able to stub it. ///ark -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20081105/489d7d95/attachment.html>