Rspec cannot find plugin routes - ruby-on-rails

Edit 1
I created an issue for rspec-rails and made a repo so people can test it themselves.
Original post
I've build a plugin according to this stackoverflow answer and added a route in my engine as follows:
# /config/routes.rb
Myplugin::Engine.routes.draw do
root to: 'pages#index'
end
My only rspec test is this:
# /spec/controllers/pages_controller_spec.rb
require "spec_helper"
describe Myplugin::PagesController do
describe "GET /admin" do
it "routes to pages#index" do
expect(get: "/admin").to route_to(controller: "pages", action: "index")
end
end
end
And in my dummy app I have this route:
# /spec/dummy/config/routes.rb
Rails.application.routes.draw do
mount Myplugin::Engine => "/admin"
end
I'm getting this error when running rspec in the root of the plugin:
Failures:
1) Myplugin::PagesController GET /admin routes to pages#index
Failure/Error: expect(get: "/admin").to route_to(controller: "pages", action: "index")
No route matches "/admin"
# ./spec/controllers/pages_controller_spec.rb:8:in `block (3 levels) in <top (required)>'
I've tried this stackoverflow answer, but it doesn't change the output.
Any ideas?
I'm using rspec 2.13.0 and rails 3.2.13.

Dummy apps should not be used in you main application, but should be used to test plugins in isolation. For example if your plugin is named Myplugin and you wanted to test the plugin in isolation without any references to your main app, could you create a dummy app at vendors/plugins/my_plugin/spec/dummy and tests at vendors/plugins/admin/specor wherever you have you plugin stored. You use a dummy app because a plugin often can't run alone. Eg devise which is a good example on a plugin, needs a main app with a ApplicationController and a user model (plus some other stuff) to work.
If you only use your plugin in this application or you just want to test that it works correctly with your main app, then just create tests normally in spec and don't create a dummy app. This would work fine, as the plugin is loaded into your main app. You would of course need to have the following in your main route file:
# config/routes.rb
Rails.application.routes.draw do
mount Myplugin::Engine => "/admin"
end
Feel free to ask if you have any questions about this.

Related

If I want to change the route in a test controllers file, do I have to edit any other files?

I want to change the route in this file from users_new_url to signup_path:
require 'test_helper'
class UsersControllerTest < ActionDispatch::IntegrationTest
test "should get new" do
get users_new_url
assert_response :success
end
end
I have tried simply replacing it,
get signup_path
but when I run rails test, it always says that signup_path is an "undefined local variable or method". Do I need to edit other files?
If it helps, the following code is from test/controllers/users_controller_test.rb.
Update: I updated my routes.rb file with get 'signup', to: 'users#new'.
Yes, you need to modify your routes.rb and setup a named route signup in order for it to be available in your application, including tests. You could review Rails Routing from the Outside In to understand how the named route helpers work.

guard error ActionController::UrlGenerationError:

I am starting to write tests for my rails application, and plan to write them prior to building the actual pages, but I am having trouble. I have searched stack overflow and google and have tried several things. The route is specified in my routes.rb file and looks like:
resources :welcome
I have the following written into my test code.
require 'rails_helper'
require 'spec_helper'
RSpec.describe "Welcomes", type: :request do
it "checks the welcome page." do
visit welcome_path
end
end
I get the following Error from guard:
Failures:
1) Welcomes checks the welcome page.
Failure/Error: visit welcome_path
ActionController::UrlGenerationError:
No route matches {:action=>"show", :controller=>"welcome"} missing required keys: [:id]
# ./spec/requests/welcomes_spec.rb:6:in `block (2 levels) in <top (required)>'
Finished in 0.00347 seconds (files took 1.61 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/requests/welcomes_spec.rb:5 # Welcomes checks the welcome page.
Change visit welcome_path to get '/welcome'
The index of a Rails resources route set is at welcomes_path. welcome_path would refer to a specific Welcome and requires an :id parameter.
If the welcome page is just a landing page and not actually a resource, you might just want config/routes.rb to contain:
get 'welcome', to: 'welcome#index`
The first welcome is the path (host.com/welcome), and the to: argument is controller#action.
The Rails routing docs are great. Give them a good read through if this didn't make sense.

Controller spec failing to find routes defined by my Rails engine

I'm building a Rails engine under Rails 3.0.12, but I'm having issues with routes when trying to write specs for my engine's controller.
The context
I've been following an Enginex layout. The engine is named Featuring and is not isolated. It does not declare routes by itself: there is no featuring/config/routes.rb file. Instead, a routes_for_feature method is provided for the main application to define engine-specific routes.
##
# featuring/lib/featuring/rails.rb
#
require 'featuring/rails/routing'
module Featuring
class Engine < ::Rails::Engine
end
end
##
# featuring/lib/featuring/rails/routing.rb
#
module ActionDispatch::Routing
class Mapper
def routes_for_feature(feature_name)
resource_name = feature_name.to_s.pluralize.to_sym
resources resource_name, :controller => "featuring/features", :only => [:index, :show], :feature => feature_name.to_s
end
end
end
Following the Enginex template, I have a Dummy app which define the routes as so:
# featuring/spec/dummy/config/routes.rb
Dummy::Application.routes.draw do
routes_for_feature :feature_model
end
The issue
Everything is working fine when I run the rails server for the Dummy app. I can browse to http://localhost:3000/feature_models and the request is successful.
I would like to spec my Featuring::FeaturesController, but I can't get it to find the routes.
Here is the spec:
# featuring/spec/controllers/features_controller_spec.rb
require 'spec_helper'
describe Featuring::FeaturesController do
context "feature_models" do
it "GET index should be successful" do
puts Rails.application.routes.routes
get :index, { :use_route => "featuring", :feature => "feature_models" }
response.should be_success
end
end
end
And here is the result of running this spec:
rspec spec/controllers/features_controller_spec.rb:7
Featuring::FeaturesController
feature_models
GET /feature_models(.:format) {:action=>"index", :controller=>"featuring/features"}
GET /feature_models/:id(.:format) {:action=>"show", :controller=>"featuring/features"}
GET index should be successful (FAILED - 1)
Failures:
1) Featuring::FeaturesController feature_models GET index should be successful
Failure/Error: get :index, { :use_route => "featuring", :feature => "feature_models" }
ActionController::RoutingError:
No route matches {:feature=>"feature_models", :controller=>"featuring/features"}
# ./spec/controllers/features_controller_spec.rb:8:in `block (3 levels) in <top (required)>'
As you can see, even if the routes are correctly defined, the spec'ed controller seems not to find them.
Something surprises me in the RoutingError: No route matches {:feature=>"feature_models", :controller=>"featuring/features"}. The action => "index" is not displayed.
I had a similar error, and I was also confused by the lack of {:action => "index"} in the route options. However, this turned out not to be the problem. ActionDispatch treats the lack of an :action as equivalent to {:action => "index"}. See:
https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/routing/route_set.rb#L545
You may be missing a request parameter in your spec, as was the case with me. Check the Parameters line in your server log when you load the page in the browser.
The trick is to add routes { } to your spec, like so:
describe Featuring::FeaturesController do
routes { Featuring::Engine.routes }
# ...
end
See also No Route Matches ... Rails Engine

rails3 and rspec2: no route matches error (while it works in the app)

In my routes.rb i have the following:
get 'home/index'
root :to => 'home#index'
If i run rake routes | grep home you see
home_index GET /home/index(.:format) {:action=>"index", :controller=>"home"}
root /(.:format) {:action=>"index", :controller=>"home"}
So, in my application.html.haml I have a link to the root_path, which nicely converts to
{:controller => "home", :action => :index}
But in every spec i run, i get the error:
No route matches {:controller=>"home"}
While if i run the application in development, everything renders
without any problem and is clickable correctly.
Does anybody have any clues as to what i did wrong?
I should add that the rails application is in the process of being
migrated from rails 2.3.11 to rails 3.
I must have overlooked something, but i can't see what.
[EDIT: more findings]
I have been trying out more stuff. The test run perfectly fine in Rubymine, or if i use the command-line and type
rspec spec/controllers/users_controller/*.spec.rb
But they do not work if I use
rake spec
What is the difference? I have deleted the lib/tasks/rspec.rake file (which was generated for rspec1) and i can see that the correct command is executed:
bundle exec rspec
So I am a bit at a loss here.
[EDIT: more testing]
When running
rspec spec/controller/**/*_spec.rb
my tests fail, when running
rspec spec/controller/accounts_controller/*_spec.rb
At the top of my files, i have the following:
describe AccountsController do
I added the type explicitly:
describe AccountsController, :type => :controller do
But that had no effect.
Does anybody have any tips?
try to add this line to your routes
resources :home, :controller => :home
I think you might have to be more specific:
get 'home/index' => 'home#index'
I found it! It took me a while, eventually I diffed the log-files that see what happens differently.
Apparently I have on spec file, where we try to test a baseclass. Inside that spec we define a new controller that derives
from that baseclass, with a dummy index method.
And also we need the routes, so inside that spec the following code was to be found:
ActionController::Routing::Routes.draw do |map|
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
end
and somehow this spec was always run first. This effectively clears the whole routing configuration i guess.
Not sure if this change is caused by rails3 or rspec2, anyway the majority of my tests are now working, just need to fix this one
test now.

'get' method in Rails controller tests throwing "no route matches" for controller scoped by module

I can't seem to work around the 'get' method in my rspec controller specs for my scoped routes.
I'm scoping the routes for my 'visitor' controllers so that they are within the 'visitor' module namespace, but are at the root of the routing. So 'mysite.com/foo' goes to the Visitor::FooController.
config/routes.rb
scope :module => 'visitor' do
resources :inquiries
end
spec/controllers/visitor/inquiries_controller_spec.rb
require 'spec_helper'
describe Visitor::InquiriesController do
describe 'GET new' do
it 'should render template visitor/inquiries/new' do
get :new
end
end
end
app/controllers/visitor/inquiries_controller.rb
class Visitor::InquiriesController < Visitor::BaseController
def new
end
end
When I run the spec I get the following error.
No route matches {:controller=>"visitor/inquiries", :action=>"new"}
I tried adding some additional parameters for get (e.g. :url => 'inquiries/new', :controller => 'inquiries') but I can't seem to get around this issue. Hitting 'inquiries/new' with my browser works fine and shows that my routes are working as expected.
I'm new to rspec so there may be some fundamental issue I'm not understanding here. Otherwise I'm looking for a way to push past this issues so I can test these 'visitor' controllers. Any help is appreciated!
The problem was fixed when I restarted my computer the next day. There seemed to be some sort of issue with Spork that was causing the problem. I'm not sure if this question can be removed, but it probably doesn't provide a lot of value to Stackoverflow.
Have a look to your config/routes.rb
uncomment follow line: match ':controller(/:action(/:id(.:format)))'
Now it should works

Resources