[rspec-users] Mixing in spec helper methods

Nick Hoffman nick at deadorange.com
Thu Nov 13 13:50:32 EST 2008


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


More information about the rspec-users mailing list