Search code examples
ruby-on-railsruby-on-rails-4rspecroutesrspec-rails

Rspec routing test fails for wildcard routes


spec/routing/user_spec.rb

require 'rails_helper'
require 'spec_helper'

describe User do
    it 'should route properly' do
        expect(get: '/users').to route_to(controller: 'users', action: 'index')
        expect(get: '/foo/bar').to route_to(controller: 'users', action: 'index')

    end
end

config/routes.rb

resources :users

match '*path', to: "users#index", via: :get

When I hit this url using my browser, this part works perfectly.

log

Started GET "/foo/bar" for 127.0.0.1 at 2014-06-12 13:42:39 +0530
Processing by UsersController#index as HTML
  Parameters: {"path"=>"foo/bar"}
  User Load (34.6ms)  SELECT "users".* FROM "users"
  Rendered users/index.html.erb within layouts/application (51.1ms)
Completed 200 OK in 261ms (Views: 222.4ms | ActiveRecord: 36.8ms)

but when I run my tests using:

rspec spec/routing/user_spec.rb

It fails with the following error

Failure/Error: expect(get: '/foo/bar').to route_to(controller: 'users', action: 'index')
       The recognized options <{"controller"=>"users", "action"=>"index", "path"=>"foo/bar"}> did not match <{"controller"=>"users", "action"=>"index"}>, difference:.
       --- expected
       +++ actual
       @@ -1 +1 @@
       -{"controller"=>"users", "action"=>"index"}
       +{"controller"=>"users", "action"=>"index", "path"=>"foo/bar"}
     # ./spec/routing/user_spec.rb:7:in `block (2 levels) in <top (required)>'

What am I doing wrong and how can I rectify this to make the tests pass?


Solution

  • Rails assigns the part of the path ('foo/bar') that matches the wildcard segment (*path) to a request parameter with the same name as the segment, so the action can see how the client got there.

    You just need to add the parameter to the result that your test expects:

    describe UserController do
      describe 'wildcard route'
        it "routes to users#index with path set to the requested path" do
          expect(get: '/foo/bar').to route_to(
            controller: 'users', action: 'index', path: 'foo/bar')
        end
      end
    end