代码之家  ›  专栏  ›  技术社区  ›  Andres Jaan Tack

如何在AuthLogic控制器规范中使用模拟模型?

  •  4
  • Andres Jaan Tack  · 技术社区  · 15 年前

    我试图在不使用夹具的情况下为控制器编写规范(而不是使用模拟模型)。这个控制器需要一个用户登录,为此我正在使用 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 合适的?

    4 回复  |  直到 13 年前
        1
  •  6
  •   Andres Jaan Tack    15 年前

    伊恩张贴 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
  •  1
  •   Simone Carletti    15 年前

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

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

    最后一个选项是传递一个模拟,它响应任何方法(您可以很容易地通过缺少方法来完成这一点)。该解决方案的问题在于,您不预先知道应该返回任何特定方法调用的值。

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

        3
  •  1
  •   Jan Minárik    13 年前

    在Rails 3中,用户会话的模拟不再有效,因为AuthLogic的用户会话不是ActiveRecord::Base的实例。解决我的问题:

    class UserSession < Authlogic::Session::Base
      extend ActiveModel::Naming
    end
    
        4
  •  0
  •   Vagmi Mudumbai    15 年前

    我发现模仿AuthLogic对象很难,我最终放弃了模仿。相反,我现在使用生成器方法 object daddy . 我的功能测试现在好多了。顺便说一句, shoulda +物体爸爸绝对是石头。Shoulda的事务上下文应该确保我的测试数据库保持干净,并且一开始我不必模拟简单的ActiveRecord对象。