2010-09-07 62 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时会导致问题。