I'm trying to figure out how to test (minitest) a route that has locale and is within a scope:
scope ":locale", locale: /#{I18n.available_locales.join("|")}/ do
get 'static_pages/about'
resources :salas
end
This doesn't work:
require 'test_helper'
class StaticPagesControllerTest < ActionController::TestCase
test "should get about" do
get :about
assert_response :success
end
end
and will produce the following output:
# Running:
E
Finished in 0.301302s, 3.3189 runs/s, 0.0000 assertions/s.
1) Error:
StaticPagesControllerTest#test_should_get_about:
ActionController::UrlGenerationError: No route matches {:action=>"about", :controller=>"static_pages"}
test/controllers/static_pages_controller_test.rb:5:in `block in <class:StaticPagesControllerTest>'
1 runs, 0 assertions, 0 failures, 1 errors, 0 skips
rake routes:
Prefix Verb URI Pattern
Controller#Action
static_pages_about GET /:locale/static_pages/about(.:format) static_pages#about {:locale=>/en|es/}
salas GET /:locale/salas(.:format) salas#index {:locale=>/en|es/}
POST /:locale/salas(.:format) salas#create {:locale=>/en|es/}
new_sala GET /:locale/salas/new(.:format) salas#new {:locale=>/en|es/}
edit_sala GET /:locale/salas/:id/edit(.:format) salas#edit {:locale=>/en|es/}
sala GET /:locale/salas/:id(.:format) salas#show {:locale=>/en|es/}
PATCH /:locale/salas/:id(.:format) salas#update {:locale=>/en|es/}
PUT /:locale/salas/:id(.:format) salas#update {:locale=>/en|es/}
DELETE /:locale/salas/:id(.:format) salas#destroy {:locale=>/en|es/}
GET /*path(.:format) redirect(301, /en/%{path})
root GET / salas#index
I think that maybe I need to pass the locale to the test but I'not sure how.
Thanks !
A little below this heading: Function Tests for your Controllers in the Rails Guide: A Guide to Testing Rails shows the get method's convention. To pass params to the method, include it as the second parameter to the call.
get :about, locale: 'en'
Related
I am following a tutorial of Rails and I have a few pages that I am adding some tests for.
I am trying to use help_path instead of :help in my pages_controller_test :
test "should get help" do
get help_path
assert_response :success
assert_select "title", "Help | #{#base_title}"
end
I added this line in my routes.rb file :
get '/help', to: 'pages#help'
But I get this error :
1) Error:
PagesControllerTest#test_should_get_help:
ActionController::UrlGenerationError: No route matches {:action=>"/help", :controller=>"pages"}
test/controllers/pages_controller_test.rb:62:in `block in '
I have tried a few solutions but none of them solved my issue.
I've also tried using this line instead :
match '/home' => 'main_pages#home', :as => :home
But it didn't work either.
My rails version is : 4.2.4
My Ruby version is : ruby 2.1.9p490 (2016-03-30 revision 54437) [x86_64-linux-gnu]
Output of $rake routes :
Prefix Verb URI Pattern Controller#Action
root GET / pages#home
help GET /help(.:format) pages#help
courses GET /courses(.:format) pages#courses
programs GET /programs(.:format) pages#programs
schools GET /schools(.:format) pages#schools
dashboard GET /dashboard(.:format) pages#dashboard
profile GET /profile(.:format) pages#profile
account GET /account(.:format) pages#account
signout GET /signout(.:format) pages#signout
EDIT :
I can use help_path .. etc in my html code without any issue, but in the test it gives that error.
Thank you :)
I've ran your tests using the repo, Rails 4.2.4, Minitest 5.10.2 and the only one test that doesn't pass is the one using get help_path. I put only the 3 tests in order to shorten the post:
PagesControllerTest#test_should_get_help_using_"get_:help" = 0.39 s = .
PagesControllerTest#test_should_get_help_using_"get_help_path" = 0.00 s = E
PagesControllerTest#test_should_get_help_using_"get_'help'" = 0.01 s = .
Finished in 0.405330s, 7.4014 runs/s, 9.8685 assertions/s.
1) Error:
PagesControllerTest#test_should_get_help_using_"get_help_path":
ActionController::UrlGenerationError: No route matches {:action=>"/help", :controller=>"pages"}
test/controllers/pages_controller_test.rb:70:in `block in <class:PagesControllerTest>'
3 runs, 4 assertions, 0 failures, 1 errors, 0 skips
What I did:
$ rm -rf Gemfile.lock (because of a json -v 1.8.1 gem error)
$ bundle
$ rake db:migrate
$ rake db:migrate RAILS_ENV=test
$ rake test test/controllers/pages_controller_test.rb -v
What you can use to make the test work with help_path as the route to test specifying the controller and action is to use:
assert_routing asserts that the routing of the given path was handled correctly and
that the parsed options (given in the expected_options hash) match
path. Basically, it asserts that Rails recognizes the route given by
expected_options.
Or:
assert_recognizes asserts that path and options match both ways; in other words, it
verifies that path generates options and then that options generates
path. This essentially combines assert_recognizes and assert_generates
into one step.
Like:
test "should get help using assert_recognizes and help_path" do
assert_recognizes({controller: 'pages', action: 'help'}, help_path)
assert_response :success
end
test "should get help using assert_routing and help_path" do
assert_routing help_path, controller: 'pages', action: 'help'
assert_response :success
end
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)
Context
I'm running into a very weird test failure that I can't explain based on my code.
When I run the spec test provided below, it will display the following error:
Failures:
1) GroupsController GET 'index' returns http success
Failure/Error: get 'index'
ActionController::UrlGenerationError:
No route matches {:action=>"index", :controller=>"groups"}
# ./spec/controllers/groups_controller_spec.rb:14:in `block (3 levels) in '
Test case
The test case for the controller and routes set in RSpec looks like this:
describe GroupsController do
before :each do
#group = FactoryGirl.create(:group)
#user = FactoryGirl.create(:user)
sign_in #user
end
describe "GET 'index'" do
it "returns http success" do
get 'index'
response.should be_success
end
end
end
Controller under test
I've written a very basic skeleton for my controller based on the test.
Currently it doesn't do a whole lot of stuff.
class GroupsController < ApplicationController
before_filter :authenticate_user!
def index
#groups = current_user.groups
end
end
Routes configured to reach the controller
The routes.rb file looks like this:
NerdCooking::Application.routes.draw do
resources :groups
devise_for :users
root :to => "home#welcome"
end
Routes
groups GET /groups(.:format) groups#index
POST /groups(.:format) groups#create
new_group GET /groups/new(.:format) groups#new
edit_group GET /groups/:id/edit(.:format) groups#edit
group GET /groups/:id(.:format) groups#show
PATCH /groups/:id(.:format) groups#update
PUT /groups/:id(.:format) groups#update
DELETE /groups/:id(.:format) groups#destroy
Question
I have tried changing the route to get "groups" => "groups#index" instead of the resources route and that works, but it's not something I want since I want to use this as a RESTful service as well.
What am I doing wrong here?
Update: Added the routes related to groups.
Okay, apparently my Guard and Spork were acting mean.
Once I restarted Guard/Spork and it all worked as expected. Looking back at the code and configuration there was no reason why stuff was going wrong.
So if anyone else is experiencing this behavior and their config and code check out. Restart!
I created a mountable engine with this routes :
Rails.application.routes.draw do
scope module: :minimalist_cms do
root to: "pages#show"
get ':id', to: "pages#show"
resources :pages
resources :page_parts
end
end
And I have this test :
require 'spec_helper'
module MinimalistCms
describe PagesController, type: :controller do
let(:page) { stub_model(Page) }
describe :show do
context "when there is a page" do
it 'should find by slug' do
Page.should_receive(:find_by_slug).and_return(page)
get :show, id: 'test'
end
end
end
end
end
And when I type rake routes I have this result :
root / minimalist_cms/pages#show
GET /:id(.:format) minimalist_cms/pages#show
pages GET /pages(.:format) minimalist_cms/pages#index
POST /pages(.:format) minimalist_cms/pages#create
new_page GET /pages/new(.:format) minimalist_cms/pages#new
edit_page GET /pages/:id/edit(.:format) minimalist_cms/pages#edit
page GET /pages/:id(.:format) minimalist_cms/pages#show
PUT /pages/:id(.:format) minimalist_cms/pages#update
DELETE /pages/:id(.:format) minimalist_cms/pages#destroy
page_parts GET /page_parts(.:format) minimalist_cms/page_parts#index
POST /page_parts(.:format) minimalist_cms/page_parts#create
new_page_part GET /page_parts/new(.:format) minimalist_cms/page_parts#new
edit_page_part GET /page_parts/:id/edit(.:format) minimalist_cms/page_parts#edit
page_part GET /page_parts/:id(.:format) minimalist_cms/page_parts#show
PUT /page_parts/:id(.:format) minimalist_cms/page_parts#update
DELETE /page_parts/:id(.:format) minimalist_cms/page_parts#destroy
It works but if I change for this, in my engine :
MinimalistCms::Engine.routes.draw do
scope module: :minimalist_cms do
root to: "pages#show"
get ':id', to: "pages#show"
resources :pages
resources :page_parts
end
end
And in my application :
mounted in my dummy application like this :
Dummy::Application.routes.draw do
mount MinimalistCms::Engine, at: '/'
end
I have this error :
Failure/Error: get :show, id: 'test'
ActionController::RoutingError:
No route matches {:id=>"test", :controller=>"minimalist_cms/pages", :action=>"show"}
And the rake routes result seem to be similar :
minimalist / MinimalistCms::Engine
root / minimalist_cms/pages#show
GET /:id(.:format) minimalist_cms/pages#show
pages GET /pages(.:format) minimalist_cms/pages#index
POST /pages(.:format) minimalist_cms/pages#create
new_page GET /pages/new(.:format) minimalist_cms/pages#new
edit_page GET /pages/:id/edit(.:format) minimalist_cms/pages#edit
page GET /pages/:id(.:format) minimalist_cms/pages#show
PUT /pages/:id(.:format) minimalist_cms/pages#update
DELETE /pages/:id(.:format) minimalist_cms/pages#destroy
page_parts GET /page_parts(.:format) minimalist_cms/page_parts#index
POST /page_parts(.:format) minimalist_cms/page_parts#create
new_page_part GET /page_parts/new(.:format) minimalist_cms/page_parts#new
edit_page_part GET /page_parts/:id/edit(.:format) minimalist_cms/page_parts#edit
page_part GET /page_parts/:id(.:format) minimalist_cms/page_parts#show
PUT /page_parts/:id(.:format) minimalist_cms/page_parts#update
DELETE /page_parts/:id(.:format) minimalist_cms/page_parts#destroy
The behaviour of the application is not changed, it works, but the test fail.
Do you have a solution?
Maybe instead of using a scope, try to use write the routes the normal way (without scope).
Now in the file where you declare the engine which inherits from Rails::Engine add isolated_namespace.
Module MinimalistCms
Class Engine < Rails::Engine
isolate_namespace MinimalistCms
end
end
Try running your test now.
I'm trying to write a very basic functional test for one of my controllers, but the problem is that it's not recognising any of my routes. They all work in the app via HTTP and can be seen in rake routes.
In fact I even added
puts ActionController::Routing::Routes.inspect
and it put out all my routes before the error.
Here's the test:
require 'test_helper'
class UsersControllerTest < ActionController::TestCase
test "should get signup" do
get :new
assert_response :success
assert_not_nil assigns(:users)
end
end
The error:
1) Error:
test_should_get_signup(UsersControllerTest):
ActionController::RoutingError: No route matches {:controller=>"users", :action=>"new"}
/test/functional/users_controller_test.rb:5:in `test_should_get_signup'
1 tests, 0 assertions, 0 failures, 1 errors
rake aborted!
Command failed with status (1): [/Users/projectzebra/.rvm/rubies/ruby-1.8.7...]
(See full trace by running task with --trace)
Rake routes:
POST /users(.:format) {:controller=>"users", :action=>"create"}
new_user_en_gb GET /users/new(.:format) {:controller=>"users", :action=>"new"}
Try adding a functional test for the route itself, see if that passes, and go from there.
Something like:
test "should route to new user" do
assert_routing '/users/new', { :controller => "users", :action => "new" }
end
It was a problem in my "journey" gem. They made routes more stricter in journey 1.0.4 which only show up on "test" environment. It is good for "developement" and "production".
** Ensure you are using exactly the same parameters as declared in routes **
Either add:
get :index, :locale => "en"
or in your Gemfile update:
gem 'journey', '1.0.3'