Rspec "No route matches" error - ruby-on-rails

I am attempting to test my sessions_controller in Rails 3 app with rspec, but keep coming across this error when I run rspec on my sessions_controller_spec.rb:
ActionController::RoutingError:
No route matches {:controller=>"sessions", :action=>"create"}
Here are all the relevant files:
routes.rb
match 'event' => 'event#create', via: [:post]
match 'event/agenda' => 'event#agenda', via: [:get]
match 'testLogin' => 'application#test_login', via: [:get]
post 'session' => 'session#create'
sessions_controller.rb
class SessionsController < ApplicationController
def create
#MY CODE HERE
end
end
sessions_controller_spec.rb
require 'spec_helper'
describe SessionsController, :type => :controller do
describe "POST #create" do
context "invalid params" do
it "returns a response with status failed if all required parameters are not passed in" do
post "create"
response.body.status.should eq("failed")
end
end
end
end
If there's any other info I can provide to help let me know. Thanks a lot!

post 'session' => 'session#create'
Your route definition is looking for a SessionController, but you have defined a SessionsController. Fix your route.
post 'session' => 'sessions#create'

Related

Rails Spec Controller Test failing with custom route

Rails 5.1
RSpec 3.6
I have a Controller:
class SessionController < ApplicationController
def new
end
end
A custom route:
get 'login' => 'sessions#new'
RSpec Test:
require 'rails_helper'
RSpec.describe SessionController, type: :controller do
describe "GET #new" do
before do
routes.draw { get "login" => "sessions#new" }
end
it "returns http success" do
get :login
expect(response).to have_http_status(:success)
end
end
end
and get error:
ActionController::UrlGenerationError: No route matches {:action=>"login", :controller=>"session"}
So "get" within a controller test seems always map to the action not the route. What should i do to get this test run? thanks in advance.
ActionController::UrlGenerationError: No route matches
{:action=>"login", :controller=>"session"}
Your controller name is SessionController, so your route should be
get 'login' => 'session#new' not get 'login' => 'sessions#new'
require 'rails_helper'
RSpec.describe SessionController, type: :controller do
describe "GET #new" do
before do
routes.draw { get "login" => "session#new" }
end
it "returns http success" do
get :login
expect(response).to have_http_status(:success)
end
end
end
Change it in your routes.rb as well.
When you are writing tests and you use the methods get, post, delete, etc., those methods assume that any parameter you pass them is the name of an action within the controller being tested. So, this works:
get :new
because it generates url_for(:controller => :sessions, :action => :new).
This doesn't work:
get '/login'
because it generates url_for(:controller => :sessions, :action => '/login').

Rspec not finding routes that exists

I'm trying to write a controller test and Rspec isn't finding routes that I know exist and work fine on a development server.
In my routes I have a catch-all route that should redeirect to a generic controller if someone goes to a route that isn't predefined.
routes.rb
namespace :tools do
match '*unmatchedpath' => "generic#show", :via => :get
end
generic_controller.rb
def show
# do stuff
end
generic_controller_spec.rb
require 'spec_helper'
describe Tools::GenericController do
describe 'GET show' do
it 'does stuff' do
get :show
end
end
Here is the error I get from rspec when I run the test above
1) Tools::GenericController GET show does stuff
Failure/Error: get :show
ActionController::RoutingError:
No route matches {:controller=>"tools/generic", :action=>"show"}
All routes work as expected on my development server so I'm not sure why Rspec isn't finding the route.
Try:
get '*unmatchedpath' => 'tools/generic#show'

controller spec failing with ActionController::RoutingError with get method

I am building a Rails 3 application, and I am a little confused with a controller spec. here what I have in the application:
routes.rb
get "/:user_name/library", :to => 'users#library', :as => :user_library
users_controller.rb
class UsersController < ApplicationController
def library
end
end
users_controller_spec.rb
describe "UsersController" do
describe "#library" do
let(:user){FactoryGirl.create(:user)}
it "renders the users/library.html.erb view" do
get :library, :parameters => {:user_name => user.user_name}
end
end
end
this example dose not run and it shows the following error
Failure/Error: get :library,:parameters => {:user_name => user.user_name}
ActionController::RoutingError:
No route matches {:parameters=>{:user_name=>"UserName"}, :controller=>"users", :action=>"library"}
Get rid of the :parameters key in your get:
get :library, :user_name => user.user_name

Rspec Controller Test No Route Matches Error

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?

Testing an RSpec controller action that can't be accessed directly

I've got a controller that can't be accessed directly, in the traditional RESTful way, but rather only through a particular url.
Normally I'm used to using get and post in my controller specs to call controller actions. Is there a way that I can exercise my controller by visiting a particular url?
EDIT:
Here is my route:
Larzworld::Application.routes.draw do
match '/auth/:provider/callback' => 'authentications#create'
devise_for :users, :controllers => {:registrations => "registrations"}
root :to => 'pages#home'
end
Here is my spec:
require 'spec_helper'
describe AuthenticationsController do
before(:each) do
request.env["omniauth.auth"] = {"provider" => "twitter", "uid" => "12345678"}
end
describe 'POST create' do
it "should find the Authentication using the uid and provider from omniauth" do
Authentication.should_receive(:find_by_provider_and_uid)
post 'auth/twitter/callback'
end
end
end
and here is the error I receive:
Failures:
1) AuthenticationsController POST create should find the Authentication using the uid and provider from omniauth
Failure/Error: post 'auth/twitter/callback'
No route matches {:action=>"auth/twitter/callback", :controller=>"authentications"}
# ./spec/controllers/authentications_controller_spec.rb:13
Finished in 0.04878 seconds
1 example, 1 failure
Controller tests use the four HTTP verbs (GET, POST, PUT, DELETE), regardless of whether your controller is RESTful. So if you have a non-RESTful route (Rails3):
match 'example' => 'story#example'
the these two tests:
require 'spec_helper'
describe StoryController do
describe "GET 'example'" do
it "should be successful" do
get :example
response.should be_success
end
end
describe "POST 'example'" do
it "should be successful" do
post :example
response.should be_success
end
end
end
will both pass, since the route accepts any verb.
EDIT
I think you're mixing up controller tests and route tests. In the controller test you want to check that the logic for the action works correctly. In the route test you check that the URL goes to the right controller/action, and that the params hash is generated correctly.
So to test your controller action, simply do:
post :create, :provider => "twitter"`
To test the route, use params_from (for Rspec 1) or route_to (for Rspec 2):
describe "routing" do
it "routes /auth/:provider/callback" do
{ :post => "/auth/twitter/callback" }.should route_to(
:controller => "authentications",
:action => "create",
:provider => "twitter")
end
end

Resources