Rails/Rspec - testing a redirect in the controller
Solution 1
This line has problem
response.should redirect_to :back
The logic is not correct. You should expect #edit
to redirect to :back
path you set before, which is /scorecard
. But you set :back
here. In the context of Rspec, :back
should be empty at each example.
To revise, just set it as
response.should redirect_to '/scorecard'
Solution 2
To make the test more readable you can do this: (rspec ~> 3.0)
expect(response).to redirect_to(action_path)
Solution 3
For testing if redirects happened, with no matching route
(just to test redirection, i used this when route is too long :D ). You can simply do like:
expect(response.status).to eq(302) #redirected
![TheLegend](https://i.stack.imgur.com/sk0Hl.png?s=256&g=1)
TheLegend
#SOreadytohelp. I am a Software Developer here in Cape Town, South Africa. I mostly work on web apps, mostly in Ruby and Rails. I started back in Nov 2011. I work for a company called Peach Payments as their head of engineering. Above all else, I love simple easy to read code. I am a student of the software development process. I find the glue that holds domains together as interesting as the domains themselves.
Updated on October 05, 2020Comments
-
TheLegend over 3 years
So I am currently writing a test for a controller in an existing controller that just didn't have one before. What I want to test is a redirect that happens when someone is not allowed to edit something vs someone that is allowed to edit it.
the controller action being edit
def edit if [email protected]? || admin? @company = @scorecard.company @custom_css_include = "confirmation_page" else redirect_to :back end end
So if a scorecard has been reviewed then only an admin can edit that score. The routes for that controller..
# scorecards resources :scorecards do member do get 'report' end resources :inaccuracy_reports, :only => [:new, :create] end
and finally the test
require 'spec_helper' describe ScorecardsController do describe "GET edit" do before(:each) do @agency = Factory(:agency) @va = Factory(:va_user, :agency => @agency) @admin = Factory(:admin) @company = Factory(:company) @scorecard = Factory(:scorecard, :level => 1, :company => @company, :agency => @agency, :reviewed => true) request.env["HTTP_REFERER"] = "/scorecard" end context "as a admin" do before(:each) do controller.stub(:current_user).and_return @admin end it "allows you to edit a reviewed scorecard" do get 'edit', :id => @scorecard.id response.status.should be(200) end end context "as a va_user" do before(:each) do controller.stub(:current_user).and_return @va end it "does not allow you to edit a reviewed scorecard" do get 'edit', :id => @scorecard.id response.should redirect_to :back end end end end
so a va when trying to edit a reviewed score will be redirected back, where an admin won't.
but when running this through rspec I get
ScorecardsController GET edit as a admin allows you to edit a reviewed scorecard as a va_user does not allow you to edit a reviewed scorecard (FAILED - 1) Failures: 1) ScorecardsController GET edit as a va_user does not allow you to edit a reviewed scorecard Failure/Error: response.should redirect_to :back Expected response to be a redirect to </scorecard> but was a redirect to <http://test.host/> # ./spec/controllers/scorecards_controller_spec.rb:33:in `block (4 levels) in <top (required)>' Finished in 0.48517 seconds 2 examples, 1 failure
so I don't know if its working or not since I set the
request.env["HTTP_REFERER"] = "/scorecard"
as the place that should be the:back
as it where. or am I missing the idea all together looking at httpstatus there are the 300 responses that I could use but I wouldn't know where to start?any help would be awesome
EDIT
I could test it by doing it like this
... response.status.should be(302)
but I got the idea from this question and it sounds like this could be powerful as it specifies the url redirected to.
Anyone have a working test like this?