2010-09-07 52 views
0

我有麻煩諷刺應該從authlogic麻煩。從摩卡應用程序嘲笑authlogic

我有以下的測試夾具:

class HomeControllerTest < ActionController::TestCase 
    context "on GET to index" do 
    setup do 
     activate_authlogic 
     UserSession.stubs(:current_user).returns(user_session) 
     get :index 
    end 

    should respond_with :success 
    end 

    def user_session 
    @user_session.stubs(:user).returns(Factory.build(:user)) 
    @user_session.stubs(:record) 
    @user_session 
    end 
end 

的問題是,在ApplicationController中的require_user方法仍然沒有得到CURRENT_USER。

def current_user 
    puts "#{defined?(@current_user)}" 
    return @current_user if defined?(@current_user) 
    @current_user = current_user_session && current_user_session.record 
end 

def require_user 
    unless current_user 
    store_location 
    flash[:notice] = "You must be logged in to access this page" 
    redirect_to login_url 
    return false 
    end 
end 

任何人都可以看到什麼是錯的?

回答

0

我認爲這個問題可能是current_user方法的最後一行。

您可能希望將其分成幾行,以使其更易讀,並且更容易診斷該聲明的哪些部分與您在測試中所期望的不同。

E.g.

@current_user = current_user_session 
@current_user.record if @current_user 
return @current_user 
+0

current_user方法的最後一行直接出自AuthLogic。在Ruby中,像'result = foo && foo.bar'這樣的行對於「將變量結果的值設置爲foo對象的bar屬性,但只有在設置了foo變量時纔是方便的簡寫」。如果foo沒有設置,'foo && foo.bar'會返回'nil'。如果設置了foo,則返回foo.bar的值。 – Chris 2010-09-07 11:12:51

+0

不夠公平,但我仍然認爲將其擴展到更多行可以更容易地弄清楚測試中出現了什麼問題。我已經更新了我的答案,以消除不正確的返回值假設。 – Shadwell 2010-09-07 11:14:33

+0

另外,'current_user'方法的返回值不是'current_user_session.record'的值嗎?如果某些事情出現問題,那麼可能是「無」。 – Shadwell 2010-09-07 11:20:07

0

它看起來像你的模擬是有點困惑;它嘲笑一個User對象(但是你使用的實例變量被稱爲@user_session),然後在該用戶上存儲一個#record方法。

此外,您正在嘲笑UserSession控制器上的current_user方法,當它在ApplicationController上實際定義時。

您試圖在您的測試中聲明的是,用戶必須登錄才能訪問Home#索引頁面。在這個測試中,你不應該關注UserSession對象 - 它並不重要。什麼重要的是,如果系統識別出一個用戶對象已經被檢索並被識別爲「current_user」,他們應該被允許訪問該頁面。

以下規格可能會制定出適合你:

class HomeControllerTest < ActionController::TestCase 
    context "on GET to index" do 
    setup do 
     activate_authlogic 
     @user = Factory.build(:user) 
     login_as_user(@user) 

     @controller.should_receive(:current_user).and_return(@user) 

     get :index 
    end 

    should respond_with :success 
    end 

    def login_as_user(user = Factory.build(:user)) 
    @controller.stubs(:current_user).returns(user) 
    end 
end 

我使用@controller變量的ActionController :: TestCase的向您提供。它表示當前正在測試的控制器的實例。

這裏需要注意的一點很重要 - 除了第4行以外 - 此測試現在不關心您使用什麼來提供身份驗證功能。只要您的應用程序定義了一個返回User對象或零對象的current_user方法,您就可以使用AuthLogic,Devise或任何其他解決方案,並且您的測試將繼續按照您的預期工作。

0

我正在使用RSpec,但嘲笑可能有關的問題。原因是current_user_session.recorddeprecated有利於current_user_session.user。不推薦使用的方法仍然在authlogic示例項目以及Railscast 160中,它可能在代碼中工作,但在模擬UserSession時會導致問題。