I have a rails application and I am trying to test the routes file.
How can one test this route in the routes.rb in rspec(minitest would be great as well):
'*unmatched_route', :to => 'application#raise_not_found!', :via => :all
According to Routing specs in RSpec you should be able to write something like this:
# in spec/routing/not_found.rb
describe 'not found' do
it 'routes to application#raise_not_found' do
expect(:get => "/an-unknown-route").to route_to(
:controller => "application",
:action => "raise_not_found!"
)
end
end
Related
Using RSpec, how do I test url_for helper method to make sure to it goes to the correct controller and action with a particular format?
I had to do the following --
Add this to spec_helper.rb:
Rspec.configure do |config|
config.include Rails.application.routes.url_helpers # url_for
end
Then:
describe "Article routing" do
it "routes to #index.atom" do
get('/articles.atom').
should route_to('articles#index', format: 'atom')
url_for(:controller => 'articles', :format => :atom, :only_path => true).
should == '/articles/index.atom'
end
end
You can test that named routes are routed to the correct place. Routing specs live in spec/routing,so the following specs would be added to spec/routing/widget_routes_spec.rb
describe "routes to the widgets controller" do
it "routes a named route" do
expect(:get => new_widget_path).
to route_to(:controller => "widgets", :action => "new")
end
end
There are a lot of other options for testing routes described in the routing specs documentation.
Rspec is not recognising my controller routes. I am using Versionist gem to version my API and I am using a path version (so /v1/ to version my API as shown below.).
constraints :subdomain => "api" do
api_version(:module => "V1", :path => {:value => "v1"}, :defaults => {:format => :json}, :default => true) do
match '/orders' => 'orders#index', :via => :get
The route in rake routes is shown as:
GET /v1/orders(.:format) V1/orders#index {:subdomain=>"api", :format=>:json}
My controller is located in app/controller/v1/orders_controller.rb.
For the rspec test, I have a orders_controller_spec.rb, I have:
require 'spec_helper'
module V1
describe OrdersController do
describe "GET #index" do
it "throws an error on incorrect params" do
get :index
end
end
end
end
The error I get is:
1) V1::OrdersApiController GET #index throws an error on incorrect param
Failure/Error: get :index
ActionController::RoutingError:
No route matches {:controller=>"v1/orders"}
What is wrong here? How come no route matches v1/orders? In rake routes, I see the route right there as shown above: GET /v1/orders(.:format) V1/orders#index {:subdomain=>"api", :format=>:json}. It says GET /v1/orders. Where is the problem here?
This is my route
match "/:type/:brand/:model/:plate" => "site/vehicles#show",
:constraints => {:plate => /[a-z]{3}\d{4}/}, :as => :vehicle
It passes the route tests
# the route test passess
it "routes to #show" do
{:get => '/carro/volksvagen/gol-2-0/abc1234'}.should route_to(
"site/vehicles#show",
:type => "carro",
:brand => "volksvagen",
:model => "gol-2-0",
:plate => "abc1234"
)
end
But after upgrading rails (3.2.0 => 3.2.8 ) which also updated journey (1.0.0 => 1.0.4), the following CONTROLLER test (which IMHO should not check for routes, which it apparently did not, back in rails 3.2.0) started failing.
describe "#show" do
it "should be success" do
get :show, :plate => #vehicle.plate
response.should be_success
end
end
It raises
Site::VehiclesController#show should be success
ActionController::RoutingError:
No route matches {:plate=>"ABC1672", :controller=>"site/vehicles",
:action=>"show"}
And even if I complete all the route vars
describe "#show" do
it "should be success" do
get :show, :plate => #vehicle.plate, :model => 'model',
:type => 'type', :brand => 'brand'
response.should be_success
end
end
I get:
# No route matches {:plate=>"ABC1586", :model=>"model", :type=>"type",
:brand=>"brand", :controller=>"site/vehicles", :action=>"show"}
The application still works, but I will not know when it stops, since my tests are failing.
Anyone solved/had similar issue?
I know 'not upgrading rails' could avoid getting this errors, as suggested in a similar question, but I don't think it is a solution.
Routing error when updating to Rails 3.2.6 or Rspec 2.11.0
Thank you in advance.
Edit:
vehicle /:type/:brand/:model/:plate(.:format) site/vehicles#show {:plate=>/[a-z]{3}\d{4}/}
I think your problem is in a mismatch between your regex and your test data. In your error message, I see:
No route matches {:plate=>"ABC1586", :model=>"model", :type=>"type",
:brand=>"brand", :controller=>"site/vehicles", :action=>"show"}
But the route has the following regex for plate:
:plate => /[a-z]{3}\d{4}/
That requires all lower-case letters; upper case letters won't match. So you need to either fix your test data, or fix the regex in your route.
This question has probably been asked a dozen times on Stack Overflow (e.g. (1), (2), (3), (4), (5)) but every time the answer seems to be different and none of them have helped me. I'm working on a Rails Engine and I'm finding that Rspec2 gets route errors, but I can reach the routes in the browser. Here's the situation:
In the engine's routes.rb:
resources :mw_interactives, :controller => 'mw_interactives', :constraints => { :id => /\d+/ }, :except => :show
# This is so we can build the InteractiveItem at the same time as the Interactive
resources :pages, :controller => 'interactive_pages', :constraints => { :id => /\d+/ }, :only => [:show] do
resources :mw_interactives, :controller => 'mw_interactives', :constraints => { :id => /\d+/ }, :except => :show
end
Excerpted output of rake routes:
new_mw_interactive GET /mw_interactives/new(.:format) lightweight/mw_interactives#new {:id=>/\d+/}
...
new_page_mw_interactive GET /pages/:page_id/mw_interactives/new(.:format) lightweight/mw_interactives#new {:id=>/\d+/, :page_id=>/\d+/}
And my test, from one of the controller specs (describe Lightweight::MwInteractivesController do):
it 'shows a form for a new interactive' do
get :new
end
...which gets this result:
Failure/Error: get :new
ActionController::RoutingError:
No route matches {:controller=>"lightweight/mw_interactives", :action=>"new"}
...and yet when I go to that route in the browser, it works exactly as intended.
What am I missing here?
ETA: To clarify a point Andreas raises: this is a Rails Engine, so rspec runs in a dummy application which includes the engine's routes in a namespace:
mount Lightweight::Engine => "/lightweight"
...so the routes shown in rake routes are prefaced with /lightweight/. That's why the route shown in the Rspec error doesn't seem to match what's in rake routes. But it does make the debugging an extra step wonkier.
ETA2: Answering Ryan Clark's comment, this is the action I'm testing:
module Lightweight
class MwInteractivesController < ApplicationController
def new
create
end
...and that's it.
I found a workaround for this. Right at the top of the spec, I added this code:
render_views
before do
# work around bug in routing testing
#routes = Lightweight::Engine.routes
end
...and now the spec runs without the routing error. But I don't know why this works, so if someone can post an answer which explains it, I'll accept that.
I think the might be something wrong higher up in you specs
how did the "lightweight" get into this line :controller=>"lightweight/mw_interactives"
the route says
new_mw_interactive GET /mw_interactives/new(.:format)
not
new_mw_interactive GET /lightweight/mw_interactives/new(.:format)
add a file spec/routing/root_routing_spec.rb
require "spec_helper"
describe "routes for Widgets" do
it "routes /widgets to the widgets controller" do
{ :get => "/" }.should route_to(:controller => "home", :action => "index")
end
end
then add a file spec/controllers/home_controller_spec.rb
require 'spec_helper'
describe HomeController do
context "GET index" do
before(:each) do
get :index
end
it {should respond_with :success }
it {should render_template(:index) }
end
end
I am doing homework but I have problem with non-RestFul routes.
My spec is:
require 'spec_helper'
describe MoviesController do
describe 'searching TMDb' do
before :each do
#fake_results = [mock('Movie'), mock('Movie')]
end
it 'should call the model method that performs TMDb search' do
Movie.should_receive(:find_in_tmdb).with('Star Wars').
and_return(#fake_results)
get :search_similar_movies, { :search_terms => 'Star Wars' }
end
end
end
In config/routes.rb I have:
resources :movies
'movies/search_similar_movies/:search_terms'
But when I run autotest it gives me error that begins with:
/usr/local/lib/ruby/gems/1.9.1/gems/actionpack-3.1.0/lib/action_dispatch/routing/mapper.rb:181:in `default_controller_and_action': missing :action (ArgumentError)
It's obvious that something is wrong is config/routes.rb. How to solve this?
Your route should be something like
resources :movies do
get 'search_similar_movies', :on => :collection
end
or
match 'movies/search_similar_movies/:search_terms' => 'movies#search_similar_movies', :via => :get