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

Anthony Carlos anthony at digitalphenom.com
Fri May 25 11:54:03 EDT 2007


Hey everyone:

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.

I want to figure out where specs for ApplicationController are  
supposed to live, and how to call them.

Here's what I've tried:

Created /spec/controllers/application_controller_spec.rb:

require File.dirname(__FILE__) + '/../spec_helper'
describe "All controllers", :shared => true do
   it "should respond to authenticate" do
     controller.should respond_to(:authenticate)
   end
   it "should respond to current_user" do
     controller.should respond_to(:current_user)
   end
end

Created /spec/controllers/concrete_controller_spec.rb:

require File.dirname(__FILE__) + '/../spec_helper'
describe ConcreteController do
   it_should_behave_like "All controllers"
end

Then, I ran rake spec:autotest, and got the following output:
ConcreteController
- should respond to current_user
- should respond to authenticate

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?

So, things are peachy except that I'm only checking that all  
controllers respond to certain methods. I want to test the logic of  
these methods, so I added the following example to my All Controllers  
behavior:

   it "should flash notice when session[:current_user_id] does not  
exist" do
     session[:current_user_id] = nil
     controller.authenticate
     flash[:notice].should == 'Please login.'
   end

My problem now, is that I get a nil object error. Specifically, in  
application.rb, I'm trying to call request.parameters and request is  
nil. It seems that request is not part of the context anymore since I  
moved the behavior out to a separate file. How do I regain access to  
request, response, assigns, flash, and session?

Thanks for your help!

-Anthony


On May 24, 2007, at 3:16 PM, Anthony Carlos wrote:

> Tim:
>
> I'm sorry, but I'm a newbie and I don't fully understand. Could you
> please give me more details?
>
> 1. Is the slightly dodgy way completely separate from using a shared
> spec?
> 2. What is the appropriate file path and name for your first example
> regarding a shared spec? Is it RAILS_ROOT/spec/controllers/
> all_controllers_spec.rb?
> 3. Does the event controller spec belong in RAILS_ROOT/spec/
> controllers/event_controller_spec.rb?
> 4. How do you actually fire off the test? Do I have to call get or
> post inside a do-end block that is attached to it_should_behave_like
> "All controllers"?
>
> e.g.,
>
> describe EventController do
>    it_should_behave_like "All controllers" do
>      get 'event1' # just an example action
>    end
> end
>
> 5. Is there any further documentation on it_should_behave_like other
> than the RDoc? It doesn't really say too much.
>
> Thanks for your help!
>
> -Anthony
>
> On May 24, 2007, at 3:18 AM, Tim Lucas wrote:
>
>> On 24/05/2007, at 5:00 PM, Wincent Colaiuta wrote:
>>
>>> The Rails ApplicationController (app/controllers/application.rb)
>>> serves as an abstract superclass for all other controllers in a  
>>> Rails
>>> application and is a good place to put methods and filters which you
>>> want all of your controllers to use. In my case I'm using it to
>>> provide methods such as "current_user" and "logged_in?" etc.
>>>
>>> By default, RSpec doesn't produce a corresponding spec file for this
>>> controller.
>>>
>>> I've made a spec file (spec/controllers/application_spec.rb) so that
>>> I can test these methods, but I'm not sure if this is the right  
>>> thing
>>> to do. Should I be testing only the non-abstract subclasses instead?
>>
>> I did it a slighty dodgy way (spec/controllers/
>> application_controller_spec.rb):
>> http://pastie.caboo.se/64123
>>
>> but nowadays you can probably use a shared spec, like so (require'd
>> from your spec helper):
>>
>> describe "All controllers", :shared => true do
>>    it "should redirect to HQ if no subdomains specified" do
>>      ...
>>    end
>> end
>>
>> and then:
>>
>> describe EventController do
>>    it_should_behave_like "All controllers"
>>    ...
>> end
>>
>> Not sure how you'd deal with something like skip_before_filter
>> though...
>>
>> -- tim
>>
>> _______________________________________________
>> rspec-users mailing list
>> rspec-users at rubyforge.org
>> http://rubyforge.org/mailman/listinfo/rspec-users
>
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users



More information about the rspec-users mailing list