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: pastie.caboo.se/103625 Also, when you''re mocking objects, a side-effect is helping you define the api of the object. 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? Thanks, Nate "fowlduck" Sutton
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: > pastie.caboo.se/103625I 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. FWIW, David> > Thanks, > > Nate "fowlduck" Sutton > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > rubyforge.org/mailman/listinfo/rspec-users >
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: >> 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. > > FWIW, > DavidWell, 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. Nate> >> >> Thanks, >> >> Nate "fowlduck" Sutton >> _______________________________________________ >> rspec-users mailing list >> rspec-users at rubyforge.org >> rubyforge.org/mailman/listinfo/rspec-users >> > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > rubyforge.org/mailman/listinfo/rspec-users
Since it''s a plugin, then I would not spec it, and spec the files that use it instead. Jim Deville 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: > pastie.caboo.se/103625 > > Also, when you''re mocking objects, a side-effect is helping you > define the api of the object. 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? > > Thanks, > > Nate "fowlduck" Sutton > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > rubyforge.org/mailman/listinfo/rspec-users >-------------- next part -------------- An HTML attachment was scrubbed... URL: rubyforge.org/pipermail/rspec-users/attachments/20071005/0c0a9093/attachment.html
AuthenticatedSystem library has tests already written for it. Just as Jim said you needn''t write specs for it. But if you did want to write spec''s for the AuthenticatedSystem then you''d create a directory inside the plugin directory with all the other directory and files pointing the paths to the files you want to spec. I''m sure it would be good practice to write spec''s for a plugin but like Jim said its practice to assume that the plugin should work. On 10/5/07, James Deville <james.deville at gmail.com> wrote:> > Since it''s a plugin, then I would not spec it, and spec the files that use > it instead. > > Jim Deville > > 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: > > pastie.caboo.se/103625 > > > > Also, when you''re mocking objects, a side-effect is helping you > > define the api of the object. 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? > > > > Thanks, > > > > Nate "fowlduck" Sutton > > _______________________________________________ > > rspec-users mailing list > > rspec-users at rubyforge.org > > rubyforge.org/mailman/listinfo/rspec-users > > > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > rubyforge.org/mailman/listinfo/rspec-users >-------------- next part -------------- An HTML attachment was scrubbed... URL: rubyforge.org/pipermail/rspec-users/attachments/20071005/7bbd00ff/attachment.html
> > 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: > > > pastie.caboo.se/103625I have speced AuthenticatedSystem in my own auth plugin: acts-as-authentable.googlecode.com Could act as a staring point for your endeavors. -- Cheers, Eivind Uggedal Engineer, Faculty of Social Science, MSc Computer Science, University of Oslo