Rails units testing: No route matches why? - ruby-on-rails

I'm trying to do some units test, this is my first time.
I don't really understand why there is No route matches.
When i run $ rake test test/controllers/products_controller_test.rb
i get this in the output of the console:
1) Error:
ProductsControllerTest#test_should_get_edit:
ActionController::UrlGenerationError: No route matches {:action=>"edit", :controller=>"products"}
test/controllers/products_controller_test.rb:20:in `block in <class:ProductsControllerTest>'
2) Error:
ProductsControllerTest#test_should_get_show:
ActionController::UrlGenerationError: No route matches {:action=>"show", :controller=>"products"}
test/controllers/products_controller_test.rb:35:in `block in <class:ProductsControllerTest>'
3) Error:
ProductsControllerTest#test_should_get_create:
ActionController::ParameterMissing: param is missing or the value is empty: product
app/controllers/products_controller.rb:59:in 'product_params'
app/controllers/products_controller.rb:18:in 'create'
test/controllers/products_controller_test.rb:15:in `block in <class:ProductsControllerTest>'
4) Error:
ProductsControllerTest#test_should_get_update:
ActionController::UrlGenerationError: No route matches {:action=>"update", :controller=>"products"}
test/controllers/products_controller_test.rb:25:in `block in <class:ProductsControllerTest>'
5) Error:
ProductsControllerTest#test_should_get_destroy:
ActionController::UrlGenerationError: No route matches {:action=>"destroy", :controller=>"products"}
test/controllers/products_controller_test.rb:30:in `block in <class:ProductsControllerTest>'
7 runs, 2 assertions, 0 failures, 5 errors, 0 skips
This is the products_controller_test.rb file:
require 'test_helper'
class ProductsControllerTest < ActionController::TestCase
test "should get index" do
get :index
assert_response :success
end
test "should get new" do
get :new
assert_response :success
end
test "should get create" do
get :create
assert_response :success
end
test "should get edit" do
get :edit
assert_response :success
end
test "should get update" do
get :update
assert_response :success
end
test "should get destroy" do
get :destroy
assert_response :success
end
test "should get show" do
get :show
assert_response :success
end
end
routes.rb file:
Rails.application.routes.draw do
resources :products
end

For all these routes (edit, update, destroy), you need to say which product you're editing/updating/destroying. If Rails doesn't know it, it can't draw the route for you.
For edit, for example, the full route would be products/:product_id/edit. So Rails will need to 'fill in' the :product_id key. If you leave it blank the route breaks.
In your code, then, if you're calling get :edit, you need to specify a product id. Like so:
get :edit, product_id: products(:test_product).id
(using the fixtures explained in the Rails test tutorial here)

Related

ActionController::UrlGenerationError: No route matches {:action=>"/users/762146111"

I've been following the Michael Hartl tutorial for learning rails and have been doing pretty well thus far, but I'm stumped on this issue which I've encountered repeatedly. I'm not skilled enough to know if there is a configuration problem in my environment or something else, but this makes NO sense to me.
In ANY of the controller tests I attempt to run, I can never get my helper URL methods to work. As an example:
test "should redirect home when not an admin" do
log_in_as(#other_user)
assert_no_difference 'User.count' do
delete user_path(#user)
end
assert redirect_to root_url
end
Generates the following error:
ERROR["test_should_redirect_home_when_not_an_admin", UsersControllerTest, 0.9899668790167198]
test_should_redirect_home_when_not_an_admin#UsersControllerTest (0.99s)
ActionController::UrlGenerationError: ActionController::UrlGenerationError: No route matches {:action=>"/users/762146111", :controller=>"users"}
test/controllers/users_controller_test.rb:60:in `block (2 levels) in <class:UsersControllerTest>'
test/controllers/users_controller_test.rb:59:in `block in <class:UsersControllerTest>'
Even simple tests like
test "should redirect index when not logged in" do
get users_path
assert_redirected_to login_url
end
Produce the same error:
ERROR["test_should_redirect_index_when_not_logged_in", UsersControllerTest, 1.5291320629185066]
test_should_redirect_index_when_not_logged_in#UsersControllerTest (1.53s)
ActionController::UrlGenerationError: ActionController::UrlGenerationError: No route matches {:action=>"/users", :controller=>"users"}
test/controllers/users_controller_test.rb:34:in `block in <class:UsersControllerTest>'
Everything I've googled about this issue hasn't helped, because for some reason I cannot determine the user_path method (or any other similar method) somehow thinks the action I'm trying to take in my controller is the path!
I've verified that my routes file is configured correctly.
Rails.application.routes.draw do
root 'static_pages#home'
get '/help' => 'static_pages#help'
get '/about' => 'static_pages#about'
get '/contact' => 'static_pages#contact'
get '/signup' => 'users#new'
post '/signup' => 'users#create'
get '/login' => 'sessions#new'
post '/login' => 'sessions#create'
delete '/logout' => 'sessions#destroy'
get 'sessions/new'
resources :users
end
I've checked that running "rails routes" has the correct routes. I've even checked in rails console that "app.user_path(1)" spits out a valid path.
At this point I'm just beyond stumped as to why these helper methods don't seem to be helping... I also don't know what they're actually called so my googling has been fairly fruitless.
To get around this issue in the tutorial, I've been using syntax like
patch :edit, { id: #user }, params: { user: { name: #user.name,
email: #user.email }}
Or
test "should redirect index when not logged in" do
get :index
assert_redirected_to login_url
end
Which seems to work.
Also here is one of my test files if that's helpful:
require 'test_helper'
class UsersControllerTest < ActionController::TestCase
def setup
#user = users(:michael)
#other_user = users(:archer)
end
test "should get new" do
get :new
assert_response :success
end
test "should redirect edit when user not logged in" do
get :edit, params: { id: #user }
assert_not flash.empty?
assert_redirected_to login_url
end
test "should redirect update when user not logged in" do
patch :edit, { id: #user }, params: { user: { name: #user.name,
email: #user.email }}
assert_not flash.empty?
assert_redirected_to login_url
end
test "should redirect index when not logged in" do
# get users_path
get :index
assert_redirected_to login_url
end
test "should redirect destroy when not logged in" do
assert_no_difference 'User.count' do
delete user_path(#user)
end
assert redirect_to login_url
end
test "should redirect home when not an admin" do
log_in_as(#other_user)
assert_no_difference 'User.count' do
delete user_path(#user)
end
assert redirect_to root_url
end
end
Please let me know what other files I can post to be helpful.
I had the same issue and I fixed it by changing the file 'users_controller_test.rb' file replacing:
class UsersControllerTest < ActionController::TestCase
for
class UsersControllerTest < ActionDispatch::IntegrationTest
But first, in your case, check that you have in your Gemfile the line:
gem 'rails', '5.0.1'
as the tutorial shows.
I can also see that you have the following test:
test 'should get new' do
get :new
assert_response :success
end
When you make the correction you'll have to change the above test to:
test 'should get new' do
get new_user_path
assert_response :success
end
After that, run your tests and you should have them all passed.
Hope it helps

Getting a rails test to pass

Following a rails tutorial but when off on a slight tangent and now cant get a test to pass.
Below is my routes file and my test file. The home test is failing and this line , to: "static_pages#home", as: "home" is the line that makes it appear. i.e remove this and it'll pass. I was wondering why someone could explain why this is failing and how to alter the test to make it pass but keeping this line in?
My routes file:
Rails.application.routes.draw do
resources :static_pages
get 'static_pages/help'
get 'static_pages/test'
get 'static_pages/home', to: "static_pages#home", as: "home"
root 'application#hello'
end
My test file:
require 'test_helper'
class StaticPagesControllerTest < ActionDispatch::IntegrationTest
test "should get home" do
get static_pages_home_url
assert_response :success
end
test "should get help" do
get static_pages_help_url
assert_response :success
end
test "should get test" do
get static_pages_test_url
assert_response :success
end
end
static_pages_home_url is the default helper method for that route with controller static_pages and action home but you set the name as home so your test should be
test "should get home" do
get home_url
assert_response :success
end

rails routing syntax errors

I am working on Michael Hartl's tutorial at railstutorial.org. I am having Difficulty In chapter 5 with getting the routing to work.
If I start with a routes file
routes.rb
Rails.application.routes.draw do
root 'static_pages#home'
get 'static_pages/help'
get 'static_pages/about'
get 'static_pages/contact'
for each of these there is a test like
static_pages_controller_test.rb
test "should get home" do
get :home
assert_response :success
assert_select "title", "Ruby on Rails Tutorial Sample App"
end
this syntax works and all the tests pass but later he wants to change the syntax using the *_path convention.
so now the tests look like
class StaticPagesControllerTest < ActionController::TestCase
test "should get home" do
get root_path
.
.
end
test "should get help" do
get help_path
.
.
end
and I updated the routes to
root 'static_pages#home'
get '/help', to: 'static_pages#help'
get '/about', to: 'static_pages#about'
get '/contact', to: 'static_pages#contact'
but now all the tests fail with the messages
ERROR["test_should_get_home", StaticPagesControllerTest, 2016-06-30 05:02:41 -0700]
test_should_get_home#StaticPagesControllerTest (1467288161.43s)
ActionController::UrlGenerationError: ActionController::UrlGenerationError:
No route matches {:action=>"/", :controller=>"static_pages"}
ERROR["test_should_get_help", StaticPagesControllerTest, 2016-06-30 05:02:41 -0700]
test_should_get_help#StaticPagesControllerTest (1467288161.43s)
ActionController::UrlGenerationError: ActionController::UrlGenerationError:
No route matches {:action=>"/help", :controller=>"static_pages"}
my controller looks something like this
class StaticPagesController < ApplicationController
def home
end
def help
end
.
.
end
if I run rake routes I get
Prefix Verb URI Pattern Controller#Action
root GET / static_pages#home
help GET /help(.:format) static_pages#help
about GET /about(.:format) static_pages#about
contact GET /contact(.:format) static_pages#contact
what am I doing wrong?
You need to rewrite these routes so that it can create dynamic route helpers for you as per your test. Write it like,
get 'static_pages/help' , as: :help
get 'static_pages/about' , as: :about
get 'static_pages/contact' , as: :contact
Read 3.6 Naming Routes.
As per your current route, those *_path will be like static_pages_about, static_pages_help etc. I am not sure how did you get the rake routes output like you have shown without using as option.
Yes Author has updated rails tutorials with 5.0.0 last week. It is suggested you update it too which will make further journey more pleasant and error free in addition to that, you will get more new things to learn in 5.0.0
update your tests/controllers/static_pages_controller_test.rb
require 'test_helper'
class StaticPagesControllerTest < ActionDispatch::IntegrationTest
test "should get home" do
get root_path
assert_response :success
assert_select "title", "Ruby on Rails Tutorial Sample App"
end
test "should get help" do
get help_path
assert_response :success
assert_select "title", "Help | Ruby on Rails Tutorial Sample App"
end
test "should get about" do
get about_path
assert_response :success
assert_select "title", "About | Ruby on Rails Tutorial Sample App"
end
test "should get contact" do
get contact_path
assert_response :success
assert_select "title", "Contact | Ruby on Rails Tutorial Sample App"
end
end
I am sure once you update your tests/controllers/static_pages_controller_test.rb you will see green test $ rails test
I'm not so sure, but what happens if you do this:
root 'static_pages#home'
get 'help', to: 'static_pages#help'
get 'about', to: 'static_pages#about'
get 'contact', to: 'static_pages#contact'

New Controller - No Route Matches update, edit, show or destroy

I'm having some difficulty getting all the RESTful routes to be setup correctly. I've taken the simplest of simple steps in my app so far.
Create new rails app
Create new controller with RESTful actions
Add resources to routes.rb
And yet 4 out of my 7 actions fail the default tests. Can anyone please explain why?
rails generate controller Employees new create update edit destroy index show
And here's the corresponding controller, employees_controller.rb
class EmployeesController < ApplicationController
def new
end
def create
end
def update
end
def edit
end
def destroy
end
def index
end
def show
end
end
Now I add the resources to routes.rb
Rails.application.routes.draw do
resources :employees
end
All the routes seem to be there, based on the output of rake routes
Prefix Verb URI Pattern Controller#Action
employees GET /employees(.:format) employees#index
POST /employees(.:format) employees#create
new_employee GET /employees/new(.:format) employees#new
edit_employee GET /employees/:id/edit(.:format) employees#edit
employee GET /employees/:id(.:format) employees#show
PATCH /employees/:id(.:format) employees#update
PUT /employees/:id(.:format) employees#update
DELETE /employees/:id(.:format) employees#destroy
But now when I run the default tests, I get 4 errors:
# Running:
.EEEE..
Finished in 0.267712s, 26.1475 runs/s, 11.2061 assertions/s.
1) Error:
EmployeesControllerTest#test_should_get_update:
ActionController::UrlGenerationError: No route matches {:action=>"update", :controller=>"employees"}
test/controllers/employees_controller_test.rb:15:in `block in <class:EmployeesControllerTest>'
2) Error:
EmployeesControllerTest#test_should_get_destroy:
ActionController::UrlGenerationError: No route matches {:action=>"destroy", :controller=>"employees"}
test/controllers/employees_controller_test.rb:25:in `block in <class:EmployeesControllerTest>'
3) Error:
EmployeesControllerTest#test_should_get_show:
ActionController::UrlGenerationError: No route matches {:action=>"show", :controller=>"employees"}
test/controllers/employees_controller_test.rb:35:in `block in <class:EmployeesControllerTest>'
4) Error:
EmployeesControllerTest#test_should_get_edit:
ActionController::UrlGenerationError: No route matches {:action=>"edit", :controller=>"employees"}
test/controllers/employees_controller_test.rb:20:in `block in <class:EmployeesControllerTest>'
7 runs, 3 assertions, 0 failures, 4 errors, 0 skips
Lastly, here is the contents of employees_controller_test.rb. As I said, these are the default tests auto-created by Rails upon generation of the controller.
require 'test_helper'
class EmployeesControllerTest < ActionController::TestCase
test "should get new" do
get :new
assert_response :success
end
test "should get create" do
get :create
assert_response :success
end
test "should get update" do
get :update
assert_response :success
end
test "should get edit" do
get :edit
assert_response :success
end
test "should get destroy" do
get :destroy
assert_response :success
end
test "should get index" do
get :index
assert_response :success
end
test "should get show" do
get :show
assert_response :success
end
end
according to dimakura's answer you have to change some routes in your test
the update method is a put (or a patch for partial changes in rails4)
test "should get update" do
put :update
assert_response :success
end
and for your edit, delete and show routes, the id is missing
test "should get edit" do
get :edit, id: 2
assert_response :success
end
Your controller test probably looks like:
class EmployeesControllerTest < ActionController::TestCase
test "should get create" do
get :create
assert_response :success
end
# other tests not shown
end
You should change it to this:
class EmployeesControllerTest < ActionController::TestCase
test "should get create" do
post :create
assert_response :success
end
# other tests should be changed accordingly
end
Use patch or put method for update, and delete for delete actions.

How to deal with RoutingError while testing with Rspec?

I created a controller called PolicyController and nested its route like this:
scope "/your"
resources :shops do
resources :policies
end
end
Now when I'm trying to test this controller I keep getting this error:
1) PoliciesController POST 'create' should be successful
Failure/Error: post 'create'
ActionController::RoutingError:
No route matches {:controller=>"policies", :action=>"create"}
# ./spec/controllers/policies_controller_spec.rb:7:in `block (3 levels) in <top (required)>'
Not sure how to set it right. Would appreciate the help.
Edit: Forgot my specs:
describe PoliciesController do
describe "POST 'create'" do
it "should be successful" do
post 'create'
response.should be_success
end
end
Do you think this will work?
post :create, :shop_id => 1
Definitely want to create a new shop in a before block.

Resources