【问题标题】:How can I use mock models in AuthLogic controller specs?如何在 AuthLogic 控制器规范中使用模拟模型?
【发布时间】:2009-06-22 05:37:49
【问题描述】:

我正在尝试在不使用固定装置(而不是使用模拟模型)的情况下为控制器编写规范。这个控制器需要一个用户登录,我使用AuthLogic,在author's recommendations之后。

describe UsersController do

  def mock_user(stubs={})
    @mock_user ||= mock_model(User, stubs)
  end

  context 'when logged in' do
    before { activate_authlogic }

    it "exposes the logged-in user as @user in response to GET (show)" do
      UserSession.create(mock_user)
      ...
    end

    ...
  end

  ...
end

这些示例都在UserSession.create(...) 行失败,报告如下:

Mock 'User_1005' received unexpected message :changed? with (no args)

我不确定如何解决这个问题;用:changed? => false 嘲讽合适吗?

【问题讨论】:

    标签: ruby-on-rails controller rspec authlogic


    【解决方案1】:

    Iain 发布了solution to using mock objects with AuthLogic。换句话说,以下助手进入spec_helpers.rb

    def current_user(stubs = {})
      @current_user ||= mock_model(User, stubs)
    end
    
    def user_session(stubs = {}, user_stubs = {})
      @current_user_session ||= mock_model(UserSession, {:user => current_user(user_stubs)}.merge(stubs))
    end
    
    def login(session_stubs = {}, user_stubs = {})
      UserSession.stub!(:find).and_return(user_session(session_stubs, user_stubs))
    end
    
    def logout
      @user_session = nil
    end
    

    我已将此纳入我的规范中,我发现它完全符合我的期望。我有为登录用户开发模拟模型的工作控制器规范,所以现在当我向用户添加字段时它们不会全部中断。 Iain 在规范中实现这一点的示例如下:

    describe SecretsController do
      before { login }
      it "should be very very secret!"
    end
    

    附:我讨厌回答自己的问题,但这是我一直在寻找的答案;我只是没早点找到。

    【讨论】:

      【解决方案2】:

      Authlogic 期望记录的行为类似于活动记录实例。您可以使用真实实例或模拟,但如果您使用模拟/存根,则必须确保它响应 Authlogic 所需的所有方法。

      我建议使用真正的活动记录对象而不是模拟对象。如果不想使用fixture,可以使用Factory。

      最后一个选项是传递一个响应任何方法的模拟(您可以通过 method_missing 轻松完成此操作)。该解决方案的问题是您事先不知道哪个值应该返回任何特定的方法调用。

      是的,您可以传递 false 但这并不是真正的解决方案。它需要手动尝试/添加默认值,直到您找到模拟对象回答所有 Authlogic 请求。但这需要您不断遵循 authlogic 进行任何内部更改,以修复对您的存根的未应答呼叫。

      【讨论】:

      • 对于会话对象,是否会发生没有那么多情况需要涵盖的情况?这就是我担心的事情:如果您有一组明显的案例要涵盖,特别是如果您可以清楚地标记它们,例如,夹具似乎工作得很好。 “admin_user”和“registered_user”。一旦它们难以标记,你就会开始得到类似“如果 quentin 登录,那么你会看到 X”的测试代码,这对我来说没有任何意义。会话是否适合固定装置?
      【解决方案3】:

      在 Rails 3 中,这种对 UserSession 的模拟不再起作用,因为 AuthLogic 的 UserSession 不是 ActiveRecord::Base 的实例。修复对我有用的问题:

      class UserSession < Authlogic::Session::Base
        extend ActiveModel::Naming
      end
      

      【讨论】:

        【解决方案4】:

        我发现模拟 authlogic 对象很难,我最终放弃了模拟。相反,我现在使用使用object daddy 的生成器方法。我的功能测试现在快乐多了。顺便说一句,shoulda+object_daddy 绝对摇滚。 Shoulda 的事务上下文确保我的测试数据库保持干净,并且我不必首先模拟简单的 activerecord 对象。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-11
          • 1970-01-01
          • 1970-01-01
          • 2014-04-07
          相关资源
          最近更新 更多