[rspec-users] Specs for ApplicationController, where to put them?

Wincent Colaiuta win at wincent.com
Tue May 29 10:50:59 EDT 2007


El 25/5/2007, a las 17:54, Anthony Carlos escribió:

> I found more information about its_should_behave_like on the
> documentation index page (duh!). The example shows how a behavior is
> factored out and put into its own describe block. However, that
> behavior is still within the same file. I think my problems stem from
> the fact that I'm using Rails and the ApplicationController is its
> own separate file.
>
> But, if I update and save concrete_controller_spec.rb, autotest tries
> to run that spec on its own and I get "Shared Behaviour 'All
> controllers' can not be found (RuntimeError)". So, I added a
> conditional require statement at the top of  
> concrete_controller_spec.rb:
>
> require File.dirname(__FILE__) + '/application_controller_spec'
> unless Spec::DSL::Behaviour.find_shared_behaviour("All controllers")
>
> That got rid of the Shared Behaviour can not be found error. Is this
> a suitable workaround, or is it too dodgy?

I faced a similar issue with shared behaviours. If you stick your  
shared behaviour at the top of a file and only use it within that  
same file then there are no problems, but if you want to put a shared  
behaviour in your spec_helper.rb or some other shared file so that it  
can be used from other files, then you run into the problem that you  
describe.

As a temporary workaround I'm bracketing the shared behaviour to make  
sure that it only gets evaluated once, similar to how you've done,  
but it does indeed feel dodgy (reminds me of conditionally including  
C header files).

What do you think about the following as possible solutions?

1. Change spec/dsl/behaviour.rb to simply skip duplicate definitions  
rather than raising an exception. Obviously, the risk here is that  
someone would accidentally name two shared behaviours the same way  
without realizing it, and only the first encountered one would be  
evaluated.

2. Add a ":global" option for shared behaviours which are intended to  
be included globally; only these behaviours would be skipped when  
evaluated multiple times, and normal shared behaviours would continue  
to exhibit the existing behaviour:

describe 'All controllers', :global => true do .. end

3. A variation on the previous suggestion: instead of using ":global"  
and ":shared" as alternatives, continue to use ":shared" in all  
cases, but allow ":global" to be passed as an additional option:

describe 'All controllers', :shared => true, :global => true do .. end

Of these solutions, I think I like the second one the best. Any other  
suggestions?

Cheers,
Wincent



More information about the rspec-users mailing list