I need to test two things:
- that certain old paths are correctly redirected to certain new paths
- that the redirect is a 301, not a 302.
I'm using Capybara for my acceptance tests, but that can't handle #2. I can test that the redirect happens, but it happens silently, so I can't see that it was a 301.
Controller tests can't handle #1. The "get", "post" etc. verbs that rspec provides for controller tests only allow you to pass in an action, not a specific path, and the redirect is implemented in a single action based on the path, as below:
# controller
class ExampleController
def redirect301
redirect_to case request.path
开发者_C百科 when '/old_a'
'/new_a'
when '/old_b'
'/new_b'
end, :status => 301
end
end
# routes.rb
['old_a', 'old_b'].each do |p|
map.connect p, :controller => :example, :action => :redirect301
end
So, what should I do?
Try this:
it "should redirect with 301" do
get :action
response.code.should == 301
end
To test response status do this - expect(response.status).to eq(301)
And to test response url do this - expect(response.location).to eq(my_path)
So altogether it should look like this:
it "should redirect with a 301 status code to my_path" do
get :action
expect(response.status).to eq(301)
expect(response.location).to eq(my_path)
end
Using rspec-rails 2.12.0 and the modern expect
syntax, this is the correct format:
it "should redirect with a 301 status code to /whatever_path" do
get :some_action
expect(response).to redirect_to '/whatever_path' # or a path helper
expect(response.code).to eq '301'
end
Notice the string 301 - when I ran this spec with an integer, it failed, comparing 301 against "301" which in Ruby are not equal.
精彩评论