Lille
2011-Jan-15 03:57 UTC
[rspec-users] [rspec-rails] how to test module behavior once and then confirm that controllers implement it?
Hi, I''m using rspec-rails (1.3.2), and wondering how to save myself the trouble of testing filters for ActionControllers when those filters call methods included from modules. Specifically, what is the recommended structure for the test of the module filter; next, how can I confirm that the controller classes that have included the module and are properly calling its methods as filters. Cracking this could save me from duplicating the testing of the full behavior of the filters in several instances, in several ActionController classes. Thanks, Lille
Nick
2011-Jan-15 05:29 UTC
[rspec-users] [rspec-rails] how to test module behavior once and then confirm that controllers implement it?
Hey Lille.> Specifically, what is the recommended structure for the test of the > module filter; >How about creating a shared example group, and referencing that? http://blog.davidchelimsky.net/2010/11/07/specifying-mixins-with-shared-example-groups-in-rspec-2/> next, how can I confirm that the controller classes > that have included the module and are properly calling its methods as > filters. >You can check if a class included a module like this: Foo.should include Bar When an object calls a method that was mixed in, the method''s called as though it truly is a part of the class. So you can just do: Module Bar def baz; end end Class Foo include Bar def something baz end end f = Foo.new f.should_receive(:baz).and_return nil f.something In the rest of your specs, it''s just a matter of stubbing out the call to "baz".> Cracking this could save me from duplicating the testing of the full > behavior of the filters in several instances, in several > ActionController classes. >I hope that helps! Nick -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110114/de2b0904/attachment.html>
Lille
2011-Jan-15 15:45 UTC
[rspec-users] [rspec-rails] how to test module behavior once and then confirm that controllers implement it?
Thanks Nick, that was helpful. I''m wondering if it''s possible to test module behavior and then test that the module behavior of interest is invoked from the before/after filter enclosing the controller action under test. To me, it seems that I''m missing a step if I don''t fill in my 4), below: 1) test included module behavior 2) test that module is included in controller class 3) test that the module methods are responsive from the host class 4) [test that the module method(s) invoked in before/after filters for actions in the host are called when their enclosed actions are.] Maybe it would be helpful to note that my module behavior is redirection. Thanks, Lille On Jan 15, 12:29?am, Nick <n... at deadorange.com> wrote:> Hey Lille. > > > Specifically, what is the recommended structure for the test of the > > module filter; > > How about creating a shared example group, and referencing that?http://blog.davidchelimsky.net/2010/11/07/specifying-mixins-with-shar... > > > next, how can I confirm that the controller classes > > that have included the module and are properly calling its methods as > > filters. > > You can check if a class included a module like this: > ? ? Foo.should include Bar > > When an object calls a method that was mixed in, the method''s called as > though it truly is a part of the class. So you can just do: > > Module Bar > ? def baz; end > end > > Class Foo > ? include Bar > > ? def something > ? ? baz > ? end > end > > f = Foo.new > f.should_receive(:baz).and_return nil > f.something > > In the rest of your specs, it''s just a matter of stubbing out the call to > "baz". > > > Cracking this could save me from duplicating the testing of the full > > behavior of the filters in several instances, in several > > ActionController classes. > > I hope that helps! > Nick > > _______________________________________________ > rspec-users mailing list > rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users
David Chelimsky
2011-Jan-15 18:34 UTC
[rspec-users] [rspec-rails] how to test module behavior once and then confirm that controllers implement it?
On Jan 15, 2011, at 9:45 AM, Lille wrote:> Thanks Nick, that was helpful. > > I''m wondering if it''s possible to test module behavior and then test > that the module behavior of interest is invoked from the before/after > filter enclosing the controller action under test. > > To me, it seems that I''m missing a step if I don''t fill in my 4), > below: > > 1) test included module behavior > 2) test that module is included in controller class > 3) test that the module methods are responsive from the host class > 4) [test that the module method(s) invoked in before/after filters for > actions in the host are called when their enclosed actions are.] > > Maybe it would be helpful to note that my module behavior is > redirection.Then _that_ ^^ is what you want to specify!!!!!!!!!!! Not 1 or 2. Maybe 3 and/or 4, but they are expressed in very procedural/structural ways. Paraphrasing myself from The RSpec Book: BDD is about behavior, not structure. It is about what code _does_, not what code _is_. In this case, the behavior is: Given these conditions When I visit one page Then I should be redirected to other page Expressed in RSpec: describe SomeController do describe "the action" do context "in some context" do post :the_action response.should redirect_to("other") end end end Please give http://blog.davidchelimsky.net/2010/11/07/specifying-mixins-with-shared-example-groups-in-rspec-2/ a read and let us know if you agree/disagree with the approach. Cheers, David> > Thanks, > > Lille > > On Jan 15, 12:29 am, Nick <n... at deadorange.com> wrote: >> Hey Lille. >> >>> Specifically, what is the recommended structure for the test of the >>> module filter; >> >> How about creating a shared example group, and referencing that?http://blog.davidchelimsky.net/2010/11/07/specifying-mixins-with-shar... >> >>> next, how can I confirm that the controller classes >>> that have included the module and are properly calling its methods as >>> filters. >> >> You can check if a class included a module like this: >> Foo.should include Bar >> >> When an object calls a method that was mixed in, the method''s called as >> though it truly is a part of the class. So you can just do: >> >> Module Bar >> def baz; end >> end >> >> Class Foo >> include Bar >> >> def something >> baz >> end >> end >> >> f = Foo.new >> f.should_receive(:baz).and_return nil >> f.something >> >> In the rest of your specs, it''s just a matter of stubbing out the call to >> "baz". >> >>> Cracking this could save me from duplicating the testing of the full >>> behavior of the filters in several instances, in several >>> ActionController classes. >> >> I hope that helps! >> Nick >> >> _______________________________________________ >> rspec-users mailing list >> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-usersCheers, David
Lille
2011-Jan-15 20:40 UTC
[rspec-users] [rspec-rails] how to test module behavior once and then confirm that controllers implement it?
David, Thanks (and, yes, I consult "The RSpec Book" often). I had familiarized myself with your reference. I guess I depart from the BDD line, because I feel that if I test a module and I test that the host implements it when expected, then that should be enough. For example, if I have a module whose single method has four possible results and then I implement it in 4 hosts, I might have to have as much as 16 tests versus my approach''s 8, alternatively. Of course, it seems like testing the invocations of the module has no facility in RSpec, due, perhaps, to the BDD approach, which, I allow, I may come to see as wiser, with more experience. Thanks for your helpful comments. Lille On Jan 15, 1:34?pm, David Chelimsky <dchelim... at gmail.com> wrote:> On Jan 15, 2011, at 9:45 AM, Lille wrote: > > > > > Thanks Nick, that was helpful. > > > I''m wondering if it''s possible to test module behavior and then test > > that the module behavior of interest is invoked from the before/after > > filter enclosing the controller action under test. > > > To me, it seems that I''m missing a step if I don''t fill in my 4), > > below: > > > 1) test included module behavior > > 2) test that module is included in controller class > > 3) test that the module methods are responsive from the host class > > 4) [test that the module method(s) invoked in before/after filters for > > actions in the host are called when their enclosed actions are.] > > > Maybe it would be helpful to note that my module behavior is > > redirection. > > Then _that_ ^^ is what you want to specify!!!!!!!!!!! Not 1 or 2. Maybe 3 and/or 4, but they are expressed in very procedural/structural ways. > > Paraphrasing myself from The RSpec Book: BDD is about behavior, not structure. It is about what code _does_, not what code _is_. > > In this case, the behavior is: > > ? Given these conditions > ? When I visit one page > ? Then I should be redirected to other page > > Expressed in RSpec: > > ? describe SomeController do > ? ? describe "the action" do > ? ? ? context "in some context" do > ? ? ? ? post :the_action > ? ? ? ? response.should redirect_to("other") > ? ? ? end > ? ? end > ? end > > Please givehttp://blog.davidchelimsky.net/2010/11/07/specifying-mixins-with-shar...a read and let us know if you agree/disagree with the approach. > > Cheers, > David > > > > > > > Thanks, > > > Lille > > > On Jan 15, 12:29 am, Nick <n... at deadorange.com> wrote: > >> Hey Lille. > > >>> Specifically, what is the recommended structure for the test of the > >>> module filter; > > >> How about creating a shared example group, and referencing that?http://blog.davidchelimsky.net/2010/11/07/specifying-mixins-with-shar... > > >>> next, how can I confirm that the controller classes > >>> that have included the module and are properly calling its methods as > >>> filters. > > >> You can check if a class included a module like this: > >> ? ? Foo.should include Bar > > >> When an object calls a method that was mixed in, the method''s called as > >> though it truly is a part of the class. So you can just do: > > >> Module Bar > >> ? def baz; end > >> end > > >> Class Foo > >> ? include Bar > > >> ? def something > >> ? ? baz > >> ? end > >> end > > >> f = Foo.new > >> f.should_receive(:baz).and_return nil > >> f.something > > >> In the rest of your specs, it''s just a matter of stubbing out the call to > >> "baz". > > >>> Cracking this could save me from duplicating the testing of the full > >>> behavior of the filters in several instances, in several > >>> ActionController classes. > > >> I hope that helps! > >> Nick > > >> _______________________________________________ > >> rspec-users mailing list > >> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users > > _______________________________________________ > > rspec-users mailing list > > rspec-us... at rubyforge.org > >http://rubyforge.org/mailman/listinfo/rspec-users > > Cheers, > David > > _______________________________________________ > rspec-users mailing list > rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users
Katrina Owen
2011-Jan-15 22:05 UTC
[rspec-users] [rspec-rails] how to test module behavior once and then confirm that controllers implement it?
On Sat, Jan 15, 2011 at 9:40 PM, Lille <lille.penguini at gmail.com> wrote:> I guess I depart from the BDD line, because I feel that if I test a > module and I test that the host implements it when expected, then that > should be enough. For example, if I have a module whose single method > has four possible results and then I implement it in 4 hosts, I might > have to have as much as 16 tests versus my approach''s 8, > alternatively.(snip)> Of course, it seems like testing the invocations of the module has no > facility in RSpec, due, perhaps, to the BDD approach, which, I allow, > I may come to see as wiser, with more experience.RSpec provides easy access to message expectations for things like that. In the case of a single module included in several places, I would probably specify the behavior in one place (either directly against the model, or using a fake wrapper if necessary), and then use a message expectation to check that you''ve hooked everything up. E.g.: require ''spec_helper'' class FilterTesterController < ApplicationController before_filter :some_filter, :only => [:wrap_some_filter] def wrap_some_filter # whatever end end describe FilterTesterController, "#some_filter" do before(:each) do MyApp::Application.routes.draw do get :wrap_some_filter, :to => ''filter_tester#wrap_some_filter'', :as => ''originating'' end end after(:each) do MyApp::Application.reload_routes! end it "does what I expect it to" do get :wrap_some_filter # expectation end end describe "One or all of your other classes that include the module" do it "is hooked up" do YourModule.should_receive(:the_method).with :some_params get :some_action # or YourClass.new.some_method or whatever end end Cheers, Katrina