Search code examples
http-redirectruby-on-rails-4rspec-railsrspec3

Strange errors in tests after updating to rspec3


After updating a project to Rspec 3, I get the following strange errors in my tests which I am not able to fix:

 undefined method `empty?' for 2:Fixnum
 # /opt/local/lib/ruby2.1/gems/2.1.0/gems/actionpack-4.2.1/lib/action_dispatch/routing/route_set.rb:251:in `block in missing_keys'
 # /opt/local/lib/ruby2.1/gems/2.1.0/gems/actionpack-4.2.1/lib/action_dispatch/routing/route_set.rb:251:in `select'
 # /opt/local/lib/ruby2.1/gems/2.1.0/gems/actionpack-4.2.1/lib/action_dispatch/routing/route_set.rb:251:in `missing_keys'
 # /opt/local/lib/ruby2.1/gems/2.1.0/gems/actionpack-4.2.1/lib/action_dispatch/routing/route_set.rb:231:in `optimized_helper'
 # /opt/local/lib/ruby2.1/gems/2.1.0/gems/actionpack-4.2.1/lib/action_dispatch/routing/route_set.rb:220:in `call'
 # /opt/local/lib/ruby2.1/gems/2.1.0/gems/actionpack-4.2.1/lib/action_dispatch/routing/route_set.rb:345:in `block (2 levels) in define_url_helper'
 # ./app/controllers/users_controller.rb:10:in `block in <class:UsersController>'

users_controller line 10 contains a redirect:

  redirect_to(user_path(current_user))

In each of these cases, current_user is a mocked User object created using mock_model(User, login: User.make_token) and has the ID value quoted in the error message (before ":Fixnum").

This happens with every redirect that contains an object. Examples:

redirect_to current_user
redirect_to user_path(current_user)
redirect_to url_for([:admin, current_user, :edit])

If I use the object's ID as in redirect_to user_path(current_user.id)), the error does not occur. However, then e.g. url_for breaks as well, since I cannot use url_for([@parent.id, @object.id, :edit]) (the objects cannot be derived from their IDs only but are needed for the path).

This only happens when using mocked objects with RSpec 3 and Rails 4.2.1. Any help would be greatly appreciated since this makes a lot of tests fail right now.


Solution

  • Rspec 3 extracted mocks support into the rspec-activemodel-mocks gem, so you might need to add rspec-activemodel-mocks to your Gemfile in order for the route helpers to behave as expected in your specs.