No route matches using rspec on a get request - ruby-on-rails

What am I forgetting?
routes:
get "/comingsoon" => "visitors#comingsoon"
resources :visitors
controller:
class VisitorsController < ApplicationController
def comingsoon
#new_visitor = Visitor.new
end
end
spec:
require 'spec_helper'
describe VisitorsController do
describe "GET /comingsoon" do
it "should be happy" do
get "/comingsoon"
response.should be_success
end
end
end
And here's the result:
✗ rspec spec/controllers/visitors_controller_spec.rb
F
Failures:
1) VisitorsController GET /comingsoon should be valid
Failure/Error: get "/comingsoon"
ActionController::RoutingError:
No route matches {:controller=>"visitors", :action=>"/comingsoon"}
# ./spec/controllers/visitors_controller_spec.rb:7:in `block (3 levels) in <top (required)>'
Finished in 0.14226 seconds
1 example, 1 failure
Failed examples:
rspec ./spec/controllers/visitors_controller_spec.rb:6 # VisitorsController GET /comingsoon should be valid
What am I forgetting?

In your spec file replace get "/comingsoon"
with get "comingsoon"
When you spec a controller with rspec the operand of the http verb (get, post, put, delete) is an action of the controller rather than a url.

Possibly daft suggestion, but you have a view right? Otherwise you have to tell your controller to render something.

Related

Rails rspec wrong expected result

I'm having problem with using rspec in ruby-on-rails app
my users_spec.rb
require 'rails_helper'
RSpec.describe 'Get /', type: :request do
it 'test / get method' do
expect(response).to have_http_status(:success)
expect(response).to include('index')
end
end
my routes.rb
Rails.application.routes.draw do
get "/" => "users#index"
end
my users_controller.rb
class UsersController < ApplicationController
def index
end
end
my index.erb
<h1>index</h1>
when I run "bundle exec rspec". , I get error like this
.F
Failures:
1) Get / test / get method
Failure/Error: expect(response).to have_http_status(:success)
expected the response to have a success status code (2xx) but it was
# ./spec/requests/users_spec.rb:5:in `block (2 levels) in <main>'
Finished in 0.11204 seconds (files took 5.18 seconds to load)
2 examples, 1 failure
Failed examples:
rspec ./spec/requests/users_spec.rb:4 # Get / test / get method
and I can't catch where is wrong..
Your spec is not correct. Your spec is not actually calling the endpoint. You need to add a get "/" call, that will actually call the endpoint
require 'rails_helper'
RSpec.describe 'Get /', type: :request do
it 'test / get method' do
get "/" #this is the missing line; this actually makes the request
expect(response).to have_http_status(:success)
expect(response).to include('index')
end
end

rspec render_template error rendering with <[]>

I have the following rspec test
context 'copy' do
let(:path) { '/sales_orders/copy' }
let(:params) { { id: sales_order.id } }
it 'copies passed in sales_order attrs' do
post path, params: params
expect(subject).to render_template('sales_orders/new')
expect(response).to have_http_status(200)
end
end
and the following in my routes
resources :sales_orders, except: %i[destroy]
The error is the following:
Failures:
1) SalesOrdersController copy copies passed in sales_order attrs
Failure/Error: expect(subject).to render_template('sales_orders/new')
expecting <"sales_orders/new"> but rendering with <[]>
# ./spec/requests/sales_order_spec.rb:435:in `block (3 levels) in <top (required)>'
Finished in 1 minute 0.96 seconds (files took 4.35 seconds to load)
1 example, 1 failure
resources :sales_orders only includes the standard routes (which you can find in the docs). However copy isn't a standard route. You can add that route and controller action like this:
# config/routes.rb
resources :sales_orders, except: %i[destroy] do
post :copy, on: :member
end
# app/controllers/sales_orders_controller.rb
class SalesOrdersController < ApplicationController
def copy
# ...
end
end
Also it looks like this action isn't doing anything, but it's just rendering a new form. In that case you might want to consider a GET request instead of POST.

test devise_token_auth: Could not find devise mapping for path "/api/v1/auth"

I am trying to test create a user. Here is
registrations_controller_spec.rb
require 'rails_helper'
RSpec.describe DeviseTokenAuth::RegistrationsController, type: :controller do
before :each do
post :create, params:{email:"w#123.com",password:"123123",password_confirmation:"123123"}
#data = JSON.parse(response.body)
end
describe "Register a user" do
it "request should be successful" do
expect(response).to have_http_status(200)
end
end
end
when i run the test i got:
Failures:
1) DeviseTokenAuth::RegistrationsController Register a user request should be successful
Failure/Error: post :create, params:{email:"w#123.com",password:"123123",password_confirmation:"123123"}
AbstractController::ActionNotFound:
Could not find devise mapping for path "/api/v1/auth".
This may happen for two reasons:
1) You forgot to wrap your route inside the scope block. For example:
devise_scope :user do
get "/some/route" => "some_devise_controller"
end
2) You are testing a Devise controller bypassing the router.
If so, you can explicitly tell Devise which mapping to use:
#request.env["devise.mapping"] = Devise.mappings[:user]
# ./spec/controllers/devise_token_auth/registrations_controller_spec.rb:5:in `block (2 levels) in <top (required)>'
Finished in 0.01477 seconds (files took 1.76 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/controllers/devise_token_auth/registrations_controller_spec.rb:10 # DeviseTokenAuth::RegistrationsController Register a user request should be successful
The message provides two ways:
1) I tried to add the first into routes but not works, where or how should i add it.
2) I added #request.env["devise.mapping"] = Devise.mappings[:user] in before block but doesn't work.
How should i solve this? thank you!
Here's my routes.rb
Rails.application.routes.draw do
namespace :api do
scope :v1 do
mount_devise_token_auth_for 'User', at: 'auth'
end
end
end
check in console: Devise.mappings, that will give you a hint.
In my case I had to call
request.env['devise.mapping'] = Devise.mappings[:api_v1_user]
instead of
request.env["devise.mapping"] = Devise.mappings[:user]

Rspec controller testing - unexpected errors/not sure how to handle it

I use this tests for FacultiesController:
describe FacultiesController do
describe "GET show" do
it "responds successfully with an HTTP 200 status code" do
get :show
expect(response).to be_success
expect(response).to have_http_status(200)
end
end
describe "GET index" do
it "responds successfully with an HTTP 200 status code" do
get :index
expect(response).to be_success
expect(response).to have_http_status(200)
end
end
end
Output:
Failures:
1) FacultiesController GET show responds successfully with an HTTP 200 status code
Failure/Error: get :show
ActionController::UrlGenerationError:
No route matches {:action=>"show", :controller=>"faculties"}
# ./spec/controllers/faculties_controller_spec.rb:5:in `block (3 levels) in <top (required)>'
2) FacultiesController GET index responds successfully with an HTTP 200 status code
Failure/Error: #faculties=Faculty.where(:university_id => #university.id).all
NoMethodError:
undefined method `id' for nil:NilClass
# ./app/controllers/faculties_controller.rb:5:in `index'
# ./spec/controllers/faculties_controller_spec.rb:13:in `block (3 levels) in <top (required)>'
1) When I run rake routes I see
faculty GET /faculties/:shortcut(.:format) faculties#show
So, I suppose I need to specify shortcut with this GET. But how?
I tried add :shortcut=>"test", but this didn't work, also tried params: {:shortcut=>"test"}. Nothing works until I just write "GET faculties/test" and also remove line get :show.
Is that as it should to be?
2)
Failure/Error: #faculties=Faculty.where(:university_id => #university.id).all
NoMethodError:
undefined method `id' for nil:NilClass
First of all, it, again, work just fine in browser testing. I use module which helps controller to define #university by subdomain.
How can I pass this to test? Should I just provide some option to get index? By the way, it is all defined in my factories.rb file, as subdomain string is stored in db.
I though may be I should invoke factories new instance in this spec before describe?
university = create(:university)
faculty = create(:faculty)
Thanks in advance.
1) You should create a new faculty and pass it's id
describe "GET show" do
let(:faculty) {FactoryGirl.create(:faculty)}
it "responds successfully with an HTTP 200 status code" do
get :show, :id => faculty.id #or get :show, :shortcut => faculty.id
expect(response).to be_success
expect(response).to have_http_status(200)
end
end
2) You should create faculty & university & pass it as params
describe "GET index" do
let(:university) {FactoryGirl.create(:university)}
before(:each) do
FactoryGirl.create(:faculty, :university_id => university.id)
end
it "responds successfully with an HTTP 200 status code" do
get :index, university_id => university.id
expect(response).to be_success
expect(response).to have_http_status(200)
end
end
Please provide index route if it wouldn't work

Ruby on Rails RSpec Routing fail

Rails newb here.
Trying to RSpec test a 200 status code for an index route.
In my index_controller_spec.rb:
require 'spec_helper'
describe IndexController do
it "should return a 200 status code" do
get root_path
response.status.should be(200)
end
end
routes.rb:
Tat::Application.routes.draw do
root to: "index#page"
end
index_controller:
class IndexController < ApplicationController
def page
end
end
When I visit on my browser all is fine but RSpec command line gives an error:
IndexController should return a 200 status code
Failure/Error: get '/'
ActionController::RoutingError:
No route matches {:controller=>"index", :action=>"/"}
# ./spec/controllers/index_controller_spec.rb:6:in `block (2 levels) in <top (required)>
'
I don't understand?!
Thanks.
Welcome to the Rails world! Testing comes in many different flavors. It appears that you're confusing a controller test with a routing test.
You're seeing this error because root_path is returning /. The get :action within an RSpec controller test is meant to call that method on that controller.
If you notice your error message, it says :action => '/'
To test your controller, change your test to:
require 'spec_helper'
describe IndexController do
it "should return a 200 status code" do
get :page
response.status.should be(200)
end
end
If you're interested in a routing test, see https://www.relishapp.com/rspec/rspec-rails/docs/routing-specs An example would be:
{ :get => "/" }.
should route_to(
:controller => "index",
:action => "page"
)

Resources