Using Rspec on Controllers
We'll create a controller called Sandbox, and write some specs, including stubs for instance methods and filters. Let's begin.
Basic Test Rig
Create a file /spec/controllers/sandbox_controller_spec.rb, with
require File.dirname(__FILE__) + '/../spec_helper'
describe SandboxController, " handling someaction" do
it "should get real value 10" do
get :someaction
assigns[:value].should equal(10)
end
Then create a file /app/controllers/sandbox_controller.rb, with
class SandboxController < ApplicationController
def someaction
@value = somemethod
end
protected
def somemethod
return 10
end
end
And give it a run,
$ script/spec spec/controllers/sandbox_controller_spec.rb --color --format specdoc
SandboxController handling someaction
- should get real value 10
Finished in 0.134328 seconds
1 example, 0 failures
Stub the Method
Now we'll stub the somemethod. In the spec file add
it "should get stubbed value 99" do
controller.stub!(:somemethod).and_return(99)
get :someaction
assigns[:value].should equal(99)
end
and run again,
SandboxController handling someaction
- should get real value 10
- should get stubbed value 99
Alternatively, you could mock it and be more specific, such as
#controller.stub!(:somemethod).and_return(99)
controller.should_receive(:somemethod).and_return(99)
Spec a Filter
Next we'll setup a little filter in the controller. Add this spec,
describe SandboxController, " handling filteredaction" do
it "should be filtered" do
get :filteredaction
assigns[:value].should be_nil
end
Create the Filter
Add to the controller,
before_filter :myfilter, :only => :filteredaction
def filteredaction
@value = 123
end
and in the protected section,
def myfilter
false
end
And give it a run,
SandboxController handling filteredaction
- should be filtered
Stub the Filter
Add this to the spec,
it "should get unfiltered 123" do
controller.stub!(:myfilter).and_return(true)
get :filteredaction
assigns[:value].should equal(123)
end
and give this one a run,
SandboxController handling filteredaction
- should be filtered
- should get unfiltered 123
Again, alternatively you could mock it,
#controller.stub!(:myfilter).and_return(true)
controller.should_receive(:myfilter).with(:no_args).once.and_return(true)
There you go :)
And this should still work if you move the protected methods out of the controller into, say, ApplicationController class (controllers/application.rb), or into a module in /lib/ that's included in your controller class(es).
Comments
>>
I have done the installation of rspec plugin but i get following error when i am testing controller_spec file
undefined method `get' for [RSpec example]:#<Class:0xb736cbc8>
any solution please pkirand2005@yahoo.co.in
>>
This is complete non-sense. Think about a person who is first time viewing your code. He can never understand what you have written
>>
That's pretty cold, mohit. It's not that bad of code, really. Thanks for the post
>>
Excellent article, the focus was on testing controllers with stubs, Mohit you need to read Rspec book in order to understand the nitty gritty... Keep up the good work.
New Comment