用摩卡从 Shoulda 模拟 authlogic

发布于 2024-09-18 05:16:19 字数 965 浏览 4 评论 0原文

我在嘲笑 shoulda 的 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

任何人都可以看到出了什么问题吗?

I am having trouble mocking authlogic from shoulda.

I have the following test fixture:

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

The problem is that the require_user method in ApplicationController is still not getting a 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

Can anyone see what is wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

慢慢从新开始 2024-09-25 05:16:19

我认为问题可能出在您的 current_user 方法的最后一行中。

您可能希望将其分成几行,以使其更具可读性,并且更容易诊断该语句的哪些部分与您在测试中所期望的不同。

例如

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

I think the problem may be something in the final line in your current_user method.

You might want to split it down into a few lines to make it more readable and easier to diagnose which of the parts of that statement are not as you'd expect in your test.

E.g.

@current_user = current_user_session
@current_user.record if @current_user
return @current_user
顾冷 2024-09-25 05:16:19

看起来你的模拟有点混乱;它模拟一个 User 对象(但您使用的实例变量称为 @user_session),然后在该用户上存根 #record 方法。

另外,您正在模拟 UserSession 控制器上的 current_user 方法,而实际上它是在 ApplicationController 上定义的。

您在测试中试图断言的是用户必须登录才能访问 Home#index 页面。在此测试中,您不应该关注 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

我正在使用 ActionController::TestCase 为您提供的 @controller 变量。它代表当前正在测试的控制器的实例。

这里需要注意的一件重要事情是——除了第 4 行之外——这个测试现在并不关心您使用什么来提供身份验证功能。只要您的应用程序定义了一个返回 User 对象或 nil 的 current_user 方法,您就可以使用 AuthLogic、Devise 或任何其他解决方案,并且您的测试将继续按您的预期工作。

It looks like your mock is a little confused; It's mocking a User object (but the instance variable you're using is called @user_session), and then stubbing a #record method on that user.

Also, you're mocking the current_user method on the UserSession controller, when it's actually defined on ApplicationController.

What you're trying to assert in your test is that a user must be logged in to access the Home#index page. In this test, you shouldn't focus on the UserSession object -- it's not as important. What is important is that if the system recognizes a user object has been retrieved and identified as the "current_user", they should be allowed to access the page.

The following spec might work out for you:

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

I'm using the @controller variable that ActionController::TestCase makes available to you. It represents the instance of the current controller being tested.

An important thing to note here is that -- with the exception of line 4 -- this test now doesn't care what you're using to provide authentication functionality. So long as your application defines a current_user method that returns a User object or nil, you could be using AuthLogic, Devise or any other solution, and your test will continue to work as you might expect.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文