How to write controller tests when you override de

2019-02-01 23:10发布

问题:

I wish to override the Devise::RegistrationsController to implement some custom functionalality. To do this, I've created a new RegistrationsController like so:

# /app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
  def new
    super
  end
end

and set up my routes like this:

devise_for :users, :controllers => { :registrations => "registrations" }

and tried to test it like this:

describe RegistrationsController do
  describe "GET 'new'" do
    it "should be successful" do
      get :new
      response.should be_success
    end
  end
end

but that gives me an error:

 1) RegistrationsController GET 'new' should be successful
 Failure/Error: get :new
 AbstractController::ActionNotFound:
   Could not find devise mapping for path "/users/sign_up".
   Maybe you forgot to wrap your route inside the scope block? For example:

       devise_scope :user do
         match "/some/route" => "some_devise_controller"
       end
 # ./spec/controllers/registrations_controller_spec.rb:13:in `block (3 levels) in <top (required)>'

So what am I doing wrong?

回答1:

The problem is that Devise is unable to map routes from the test back to the original controller. That means that while your app actually works fine if you open it in the browser, your controller tests will still fail.

The solution is to add the devise mapping to the request before each test like so:

before :each do
  request.env['devise.mapping'] = Devise.mappings[:user]
end


回答2:

Your route should look like this:

devise_for :users, :controllers => { :registrations => "registrations" } do
  get "/users/sign_up/:invitation_token" => 'registrations#new'
end