[rspec-users] Specs and Libs

Nathan Sutton nathan.sutton at gmail.com
Thu Oct 4 07:30:34 EDT 2007

On Oct 4, 2007, at 6:24 AM, David Chelimsky wrote:

> On 10/4/07, Nathan Sutton <nathan.sutton at gmail.com> wrote:
>> How would I go about writing specs for a lib, particularly one with
>> all protected and private methods.  I'm trying to spec the
>> AuthenticatedSystem library from the rails restful_authentication
>> plugin:
>> http://pastie.caboo.se/103625
> I think there are a few ways you can handle this. One would be to
> create a class that includes that module and add public methods to
> that class that access the protected ones:
> class ExampleController
>   include AuthenticatedSystem
>   def has_logged_in_user?
>     logged_in?
>   end
> end
> controller.should_not have_logged_in_user
> log_in #waving hands...
> controller.should have_logged_in_user
> Other possibilities would be to use instance_eval or make the methods
> public from the example using send(:public, :logged_in?). I to avoid
> that sort of thing when I'm developing code spec-first, but in the
> case of back-filling specs on existing code I don't mind using brute
> force like that. It's brittle, and in the end I might want to change
> the design, but not until I've got it fairly well covered so I can
> refactor in peace.
>> Also, when you're mocking objects, a side-effect is helping you
>> define the api of the object.
> Actually, I think that's the whole point of mock objects and not a
> side effect at all. If anything, the side-effect is isolation :)
>> Is there a way to get all the
>> behaviors that have been mocked for a class and its objects?  Is
>> there a way to automagically compare the output against what is
>> actually defined?
> Mocha allows you to do this using responds_like:
> account = mock('Account').responds_like(Account)
> account.expects(:withdraw)
> If account does not respond_to?(:withdraw), then you get a failure.
> Personally, I never use this. In practice, it means that every time I
> say object_i_am_NOT_defining_right_now.expects 
> (:method_that_does_not_exist_yet)
> I have to stop what I'm working on and add this method to the real
> object. In the best case scenario, I'm disciplined about it and I
> start writing specs for the new behaviour - completely losing the
> context I was just in. In the less-than-best-case scenario, I'm not as
> disciplined and I just add an empty method declaration in order to
> quiet the noise. Neither case is desirable for me.
> We've batted the idea of adding support for something like this to
> rspec's mock framework, but with a command line switch to turn it on
> (default behaviour would be that it stays quiet). There's an open RFE
> for this in the tracker. I'm just not sure that it's worth the trouble
> when you consider the implications of behaviour getting added at
> runtime and the like.
> David

Well, really, I wouldn't want it to behave any differently, I would  
just like a way to, at some point, check that I'm actually  
implementing them all, in case I forgot something.  Raising  
exceptions and errors would be unacceptable, I agree. Also if I  
decide to remove a method and a spec in the future and I overlook  
that one spec that uses that method, it would be nice to know.  I  
know integration testing should pick this up, but even if it did then  
this would be useful as a diagnostic tool.


>> Thanks,
>> Nate "fowlduck" Sutton
>> _______________________________________________
>> rspec-users mailing list
>> rspec-users at rubyforge.org
>> http://rubyforge.org/mailman/listinfo/rspec-users
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users

More information about the rspec-users mailing list