[rspec-users] Mixing in spec helper methods
Ben Mabey
ben at benmabey.com
Wed Nov 12 16:38:08 EST 2008
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-users
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/
More information about the rspec-users
mailing list