2011-07-12 82 views
17

我设计了在我的Rails应用程序上设置的身份验证和注册。我使用after_sign_in_path_for()来根据各种情况自定义用户登录时的重定向。如何测试after_sign_in_path_for(资源)?

我在问的是如何测试这种方法?这似乎很难隔离,因为它会自动通过设计,当用户SIGNES在叫我想做的事情是这样的:

describe ApplicationController do 
    describe "after_sign_in_path_for" do 
    before :each do 
     @user = Factory :user 
     @listing = Factory :listing 
     sign_in @user 
    end 

    describe "with listing_id on the session" do 
     before :each do 
     session[:listing_id] = @listing.id 
     end 

     describe "and a user in one team" do 
     it "should save the listing from the session" do 
      expect { 
      ApplicationController.new.after_sign_in_path_for(@user) 
      }.to change(ListingStore, :count).by(1) 
     end 

     it "should return the path to the users team page" do 
      ApplicationController.new.after_sign_in_path_for(@user).should eq team_path(@user.team) 
     end 
     end 
    end 
    end 
end 

但是这显然不是这样做,因为我刚刚得到一个错误的方式:

Failure/Error: ApplicationController.new.after_sign_in_path_for(@user) 
RuntimeError: 
    ActionController::Metal#session delegated to @_request.session, but @_request is nil: #<ApplicationController:0x00000104581c68 @_routes=nil, @_action_has_layout=true, @_view_context_class=nil, @_headers={"Content-Type"=>"text/html"}, @_status=200, @_request=nil, @_response=nil> 

那么,我该如何测试这种方法呢?

回答

31

奇怪的是,今天我很想知道这件事。这是我想出来的。我创建了一个ApplicationController的匿名子类。在这个匿名子类中,我公开了我想测试的保护方法作为公共方法。然后我直接测试它们。

describe ApplicationController do 
    controller do 
    def after_sign_in_path_for(resource) 
     super resource 
    end 
    end 

    before (:each) do 
    @user = FactoryGirl.create(:user) 
    end 

    describe "After sigin-in" do 
    it "redirects to the /jobs page" do 
     controller.after_sign_in_path_for(@user).should == jobs_path 
    end 
    end 

end 
+0

非常好!我不知道它是如何工作的,但它的工作! –

+0

谢谢!你刚刚救了我另一个设计头痛 –

+0

谢谢你太多。我正在考虑这个问题,但对这个controller.after_sign_in_path_for(@user)没有任何想法。作业==作业_路径 – Ricbermo

4

在类似的注释 - 如果你想在注册后测试重定向,你有两个选择。

首先,你可以按照与上述及非常直接的模式在RegistrationsController测试方法:

require 'spec_helper' 

describe RegistrationsController do 

    controller(RegistrationsController) do 
    def after_sign_up_path_for(resource) 
     super resource 
    end 
    end 

    describe "After sign-up" do 
    it "redirects to the /organizations/new page" do 
     @user = FactoryGirl.build(:user) 
     controller.after_sign_up_path_for(@user).should == new_organization_path 
    end 
    end 
end 

或者,您也可以采取更多的集成测试排序的方法,并做到以下几点:

require 'spec_helper' 

describe RegistrationsController do 

    describe "After successfully completing the sign-up form" do 

    before do 
     @request.env["devise.mapping"] = Devise.mappings[:user] 
    end 

    it "redirects to the new organization page" do 
     post :create, :user => {"name" => "Test User", "email" => "[email protected]", "password" => "please"} 
     response.should redirect_to(new_organization_path) 
    end 
    end 
end 
+0

对于集成方法012为+1 –

0
context "without previous page" do 
    before do 
    Factory.create(:user, email: "[email protected]", password: "123456", password_confirmation: "123456") 
    request.env["devise.mapping"] = Devise.mappings[:user] 
    post :create, user: { email: "[email protected]", password: "123456" } 
    end 
end 

    it { response.should redirect_to(root_path) } 
context "with previous page" do 
    before do 
    Factory.create(:user, email: "[email protected]", password: "123456", password_confirmation: "123456") 
    request.env["devise.mapping"] = Devise.mappings[:user] 
    request.env['HTTP_REFERER'] = 'http://test.com/restaurants' 
    post :create, user: { email: "[email protected]", password: "123456" } 
    end 

    it { response.should redirect_to("http://test.com/restaurants") } 
end 
+0

这段代码的一些解释会有帮助 –

0

对于新人,我建议做这种方式:

RSpec.describe ApplicationController, type: :controller do 
    let(:user) { create :user } 

    describe "After sing-in" do 
    it "redirects to the /yourpath/ home page" do 
     expect(subject.after_sign_in_path_for(user)).to eq(yourpath_root_path) 
    end 
    end 
end 
+0

可以澄清一下'subject '是? –

+0

@ Abdul-RahmanAhmad'ApplicationController'与RSpec.describe中的ApplicationController一样。 –

+0

谢谢,明白了 –