I''ve written a module for my specs that contains a helper method, and am mixing the module into my specs with #include . It seems that the method must be called with an #it block. If it isn''t, this error occurs: ... in `method_missing'': undefined method `it_should_behave_like_an_action_that_sets_the_flash_notice'' for Spec::Rails::Example::ControllerExampleGroup::Subclass_1:Class (NoMethodError) from ./spec/controllers/properties_controller_spec.rb:8 Is there a way to call my helper method from outside of an #it block? Here''s the code: http://pastie.org/312680 Thanks! Nick
Nick Hoffman wrote:> I''ve written a module for my specs that contains a helper method, and > am mixing the module into my specs with #include . It seems that the > method must be called with an #it block. If it isn''t, this error occurs: > > ... in `method_missing'': undefined method > `it_should_behave_like_an_action_that_sets_the_flash_notice'' for > Spec::Rails::Example::ControllerExampleGroup::Subclass_1:Class > (NoMethodError) from ./spec/controllers/properties_controller_spec.rb:8 > > Is there a way to call my helper method from outside of an #it block? > Here''s the code: > http://pastie.org/312680 > > Thanks! > Nick > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-usersIt looks like you want those methods in your module as class method, not instance methods. Try extending, not including, your module (extend AuthSpecHelpers.) You might want to read my post about creating rspec macros as well: http://www.benmabey.com/2008/06/08/writing-macros-in-rspec/ -Ben
Nick Hoffman <nick at deadorange.com> writes:> I''ve written a module for my specs that contains a helper method, and > am mixing the module into my specs with #include . It seems that the > method must be called with an #it block. If it isn''t, this error > occurs: > > ... in `method_missing'': undefined method > it_should_behave_like_an_action_that_sets_the_flash_notice'' for > Spec::Rails::Example::ControllerExampleGroup::Subclass_1:Class > (NoMethodError) from > ./spec/controllers/properties_controller_spec.rb:8 > > Is there a way to call my helper method from outside of an #it block? > Here''s the code: > http://pastie.org/312680You want extend instead of include. Also, if you want to share this among many example groups, you can do it in the config block instead of extending it in every single example group: Spec::Runner.configure do |config| config.extend AuthSpecHelpers end You can even do it for particular example group types if you want: Spec::Runner.configure do |config| config.extend AuthSpecHelpers, :type => :controller end Pat
On Tue, Nov 11, 2008 at 6:39 PM, Pat Maddox <pergesu at gmail.com> wrote:> Nick Hoffman <nick at deadorange.com> writes: > >> I''ve written a module for my specs that contains a helper method, and >> am mixing the module into my specs with #include . It seems that the >> method must be called with an #it block. If it isn''t, this error >> occurs: >> >> ... in `method_missing'': undefined method >> it_should_behave_like_an_action_that_sets_the_flash_notice'' for >> Spec::Rails::Example::ControllerExampleGroup::Subclass_1:Class >> (NoMethodError) from >> ./spec/controllers/properties_controller_spec.rb:8 >> >> Is there a way to call my helper method from outside of an #it block? >> Here''s the code: >> http://pastie.org/312680 > > You want extend instead of include. > > Also, if you want to share this among many example groups, you can do it > in the config block instead of extending it in every single example > group: > > Spec::Runner.configure do |config| > config.extend AuthSpecHelpers > end > > You can even do it for particular example group types if you want: > > Spec::Runner.configure do |config| > config.extend AuthSpecHelpers, :type => :controller > endNote that config.extend was only added recently, in rspec-1.1.9. Cheers, David> > Pat > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
On 2008-11-11, at 19:31, Ben Mabey wrote:> Nick Hoffman wrote: >> I''ve written a module for my specs that contains a helper method, >> and am mixing the module into my specs with #include . It seems >> that the method must be called with an #it block. If it isn''t, this >> error occurs: >> >> ... in `method_missing'': undefined method >> `it_should_behave_like_an_action_that_sets_the_flash_notice'' for >> Spec::Rails::Example::ControllerExampleGroup::Subclass_1:Class >> (NoMethodError) from ./spec/controllers/ >> properties_controller_spec.rb:8 >> >> Is there a way to call my helper method from outside of an #it >> block? Here''s the code: >> http://pastie.org/312680 >> >> Thanks! >> Nick >> > > It looks like you want those methods in your module as class method, > not instance methods. Try extending, not including, your module > (extend AuthSpecHelpers.) You might want to read my post about > creating rspec macros as well: > http://www.benmabey.com/2008/06/08/writing-macros-in-rspec/ > > -BenThat was post was gold, Ben. It cleared up most of my questions and confusion regarding #include, #extend, and mix-ins. Thanks, mate.
On 2008-11-11, at 19:39, Pat Maddox wrote:> Nick Hoffman <nick at deadorange.com> writes: >> I''ve written a module for my specs that contains a helper method, and >> am mixing the module into my specs with #include . It seems that the >> method must be called with an #it block. If it isn''t, this error >> occurs: >> >> ... in `method_missing'': undefined method >> it_should_behave_like_an_action_that_sets_the_flash_notice'' for >> Spec::Rails::Example::ControllerExampleGroup::Subclass_1:Class >> (NoMethodError) from >> ./spec/controllers/properties_controller_spec.rb:8 >> >> Is there a way to call my helper method from outside of an #it block? >> Here''s the code: >> http://pastie.org/312680 > > You want extend instead of include. > > Also, if you want to share this among many example groups, you can > do it > in the config block instead of extending it in every single example > group: > > Spec::Runner.configure do |config| > config.extend AuthSpecHelpers > end > > You can even do it for particular example group types if you want: > > Spec::Runner.configure do |config| > config.extend AuthSpecHelpers, :type => :controller > end > > PatThat''s convenient. What I''ve done is add this to the beginning: require ''spec/shared/auth_spec_helpers'' and add this to the ''config'' block: config.extend AuthSpecHelpers, :type => :controller of spec_helper.rb . Is that a suitable, or preferred, method of extending the helper methods in the AuthSpecHelpers module to controller specs? Thanks, Nick
On 2008-11-11, at 19:49, David Chelimsky wrote:> On Tue, Nov 11, 2008 at 6:39 PM, Pat Maddox <pergesu at gmail.com> wrote: >> You can even do it for particular example group types if you want: >> >> Spec::Runner.configure do |config| >> config.extend AuthSpecHelpers, :type => :controller >> end > > Note that config.extend was only added recently, in rspec-1.1.9. > > Cheers, > DavidThanks for remembering that I''m using an old version of RSpec and RSpec-Rails, mate ;) That was enough of a reason to upgrade, so now I''m running 1.1.11 of the plugins. Hoorah! -Nick
On 2008-11-11, at 19:31, Ben Mabey wrote:> Nick Hoffman wrote: >> I''ve written a module for my specs that contains a helper method, >> and am mixing the module into my specs with #include . It seems >> that the method must be called with an #it block. If it isn''t, this >> error occurs: >> >> ... in `method_missing'': undefined method >> `it_should_behave_like_an_action_that_sets_the_flash_notice'' for >> Spec::Rails::Example::ControllerExampleGroup::Subclass_1:Class >> (NoMethodError) from ./spec/controllers/ >> properties_controller_spec.rb:8 >> >> Is there a way to call my helper method from outside of an #it >> block? Here''s the code: >> http://pastie.org/312680 >> >> Thanks! >> Nick >> _______________________________________________ >> rspec-users mailing list >> rspec-users at rubyforge.org >> http://rubyforge.org/mailman/listinfo/rspec-users > It looks like you want those methods in your module as class method, > not instance methods. Try extending, not including, your module > (extend AuthSpecHelpers.) You might want to read my post about > creating rspec macros as well: > http://www.benmabey.com/2008/06/08/writing-macros-in-rspec/ > > -BenAfter digesting that post again, especially the contents of #self.included , I noticed that one could alternatively do this: module AssignMacro def self.extended(receiver) receiver.extend ExampleGroupMethods receiver.send :include, ExampleMethods end end describe UserPhotosController do describe "GET ''users/1/photos/2''" do extend AssignMacro # ... end end Is one approach more preferable? Or should one do this so that both "include AssignMacro" and "extend AssignMacro" give the same, desired, result?: module AssignMacro def self.included(receiver) receiver.extend ExampleGroupMethods receiver.send :include, ExampleMethods end class << self alias_method :extended, :included end end Thanks for your input, guys. -Nick
Nick Hoffman wrote:> On 2008-11-11, at 19:31, Ben Mabey wrote: >> Nick Hoffman wrote: >>> I''ve written a module for my specs that contains a helper method, >>> and am mixing the module into my specs with #include . It seems that >>> the method must be called with an #it block. If it isn''t, this error >>> occurs: >>> >>> ... in `method_missing'': undefined method >>> `it_should_behave_like_an_action_that_sets_the_flash_notice'' for >>> Spec::Rails::Example::ControllerExampleGroup::Subclass_1:Class >>> (NoMethodError) from ./spec/controllers/properties_controller_spec.rb:8 >>> >>> Is there a way to call my helper method from outside of an #it >>> block? Here''s the code: >>> http://pastie.org/312680 >>> >>> Thanks! >>> Nick >>> _______________________________________________ >>> rspec-users mailing list >>> rspec-users at rubyforge.org >>> http://rubyforge.org/mailman/listinfo/rspec-users >> It looks like you want those methods in your module as class method, >> not instance methods. Try extending, not including, your module >> (extend AuthSpecHelpers.) You might want to read my post about >> creating rspec macros as well: >> http://www.benmabey.com/2008/06/08/writing-macros-in-rspec/ >> >> -Ben > > After digesting that post again, especially the contents of > #self.included , I noticed that one could alternatively do this: > > module AssignMacro > def self.extended(receiver) > receiver.extend ExampleGroupMethods > receiver.send :include, ExampleMethods > end > end > > describe UserPhotosController do > describe "GET ''users/1/photos/2''" do > extend AssignMacro > # ... > end > end > > Is one approach more preferable? Or should one do this so that both > "include AssignMacro" and "extend AssignMacro" give the same, desired, > result?: > > module AssignMacro > def self.included(receiver) > receiver.extend ExampleGroupMethods > receiver.send :include, ExampleMethods > end > > class << self > alias_method :extended, :included > end > end > > Thanks for your input, guys. > -Nick > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-usersSome people would say that using the included or extended module hooks like that are evil.[1] That said it is a very common ruby idiom even if it is bad. If you are going to use the evil idiom then I would suggest using include and not extend since it is the idiom. :) Another way to do it that wouldn''t take advantage of the evil hooks would be: describe UserPhotosController do describe "GET ''users/1/photos/2''" do extend AssignMacro::ExampleGroupMethods include AssignMacro::ExampleMethods # ... end Of course that is somewhat annoying to type everywhere. So perhaps you could add another example group method that would mix in macors.. likes so: describe UserPhotosController do describe "GET ''users/1/photos/2''" do use_macro AssignMacro # ... end end The ''use_maco'' would be a module that you mix in onto all rspec''s example group methods that would simply include and extend the given module''s ExampleMethods and ExampleGroupMethods modules respectively. The ''use_macro'' is probably more clear than the hooks. Just a thought. -Ben 1. http://olabini.com/blog/2008/09/evil-hook-methods/
On 2008-11-12, at 16:38, Ben Mabey wrote:> Nick Hoffman wrote: >> After digesting that post again, especially the contents of >> #self.included , I noticed that one could alternatively do this: >> >> module AssignMacro >> def self.extended(receiver) >> receiver.extend ExampleGroupMethods >> receiver.send :include, ExampleMethods >> end >> end >> >> describe UserPhotosController do >> describe "GET ''users/1/photos/2''" do >> extend AssignMacro >> # ... >> end >> end >> >> Is one approach more preferable? Or should one do this so that both >> "include AssignMacro" and "extend AssignMacro" give the same, >> desired, result?: >> >> module AssignMacro >> def self.included(receiver) >> receiver.extend ExampleGroupMethods >> receiver.send :include, ExampleMethods >> end >> >> class << self >> alias_method :extended, :included >> end >> end >> >> Thanks for your input, guys. >> -Nick > > Some people would say that using the included or extended module > hooks like that are evil.[1] That said it is a very common ruby > idiom even if it is bad. If you are going to use the evil idiom > then I would suggest using include and not extend since it is the > idiom. :) > > Another way to do it that wouldn''t take advantage of the evil hooks > would be: > > describe UserPhotosController do > describe "GET ''users/1/photos/2''" do > extend AssignMacro::ExampleGroupMethods > include AssignMacro::ExampleMethods > # ... > end > > Of course that is somewhat annoying to type everywhere. So perhaps > you could add another example group method that would mix in > macors.. likes so: > > describe UserPhotosController do > describe "GET ''users/1/photos/2''" do > use_macro AssignMacro > # ... > end > end > > The ''use_maco'' would be a module that you mix in onto all rspec''s > example group methods that would simply include and extend the given > module''s ExampleMethods and ExampleGroupMethods modules respectively. > > The ''use_macro'' is probably more clear than the hooks. Just a > thought. > > -Ben > > > 1. http://olabini.com/blog/2008/09/evil-hook-methods/The "evil hook methods" article explained exactly how I was feeling. Everyone''s different, but I feel dirty extending the receiver in #included , and vice versa. I''ve decided to go along with your first suggested alternative: ## spec/spec_helper.rb # ..snip.. Spec::Runner.configure do |config| # ..snip.. config.extend AuthSpecHelpers::ExampleGroupMethods, :type => :controller config.include AuthSpecHelpers::ExampleMethods, :type => :controller end Thanks again for taking the time to explain all of this, Ben. I really learned a lot. Cheers, Nick