Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do routing specs support redirect routes? [RSpec]

After digging fairly deeply on this issue, I've come to an impasse between my understanding of the documentation and my results.

According to https://www.relishapp.com/rspec/rspec-rails/v/2-8/docs/routing-specs/route-to-matcher, we should be able to write the following:

#rspec-rails (2.8.1) #rspec (>= 1.3.1) #rspec-core (~> 2.8.0)  # routing spec require "spec_helper"  describe BusinessUsersController do   describe "routing" do     it "routes to some external url" do       get("/business_users/7/external_url").should route_to("http://www.google.com")     end   end end  # routes.rb BizeebeeBilling::Application.routes.draw do    resources :business_users do     member do       get "external_url" => redirect("http://www.google.com")     end   end end 

Running this spec produces the following results: Failures:

  1) BusinessUsersController routing routes to some external url      Failure/Error: assert_routing "/business_users/7/external_url", "http://www.google.com"      ActionController::RoutingError:        No route matches "/business_users/7/external_url"      # ./spec/routing/business_users_routing_spec.rb:19:in `block (3 levels) in <top (required)>' 

I have not been able to find anyone reporting this specific issue anywhere.

Added detail: the route is resolved perfectly well when testing manually.

like image 441
zealoushacker Avatar asked May 31 '12 23:05

zealoushacker


1 Answers

Routing specs/tests specialize in testing whether a route maps to a specific controller and action (and maybe some parameters too).

I dug into the internals of Rails and Journey a bit. RSpec and Rails (basically, some details left out) use Rails.application.routes.recognize_path to answer the question "is this routable?"

For example:

 $ rails console > Rails.application.routes.recognize_path("/business_users/1", method: "GET")  => {:action=>"show", :controller=>"business_users", :id=>"1"} 

However, there's no controller on the other end of /business_users/1/external_url. In fact, to perform the redirect, Rails has created an instance of ActionDispatch::Routing::Redirect, which is a small Rack application. No Rails controller is ever touched. You're basically mounting another Rack application to perform the redirection.

To test the redirect, I recommend using a request spec instead (a file in spec/requests). Something like:

require "spec_helper"  describe "external redirection" do   it "redirects to google.com" do     get "/business_users/1/external_url"     response.should redirect_to("http://www.google.com")   end end

This tests the route implicitly, and allows you to test against the redirection.

like image 112
Andy Lindeman Avatar answered Sep 30 '22 14:09

Andy Lindeman