2009-06-22 62 views
4

我想写一个控制器的规格而不使用灯具(而不是使用模拟模型)。此控制器要求用户登录,我正在使用AuthLogic,跟在author's recommendations之后。如何在AuthLogic控制器规格中使用模拟模型?

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是否合适?

回答

6

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 

P.S.我讨厌回答我自己的问题,但这是我正在寻找的答案;我只是没有找到足够的时间。

1

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

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

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

是的,你可以通过false但这不是一个真正的解决方案。这需要手动尝试/添加默认值,直到找到模拟对象回答所有Authlogic请求。但是这会要求你不断地关注authlogic的任何内部变化,以解决未接的电话到你的存根。

+0

是否会发生,与会话对象,有没有这么多的情况下覆盖? 以下是我所担心的:如果您有一套明显的病例需要覆盖,并且特别是您可以明显标记它们, “admin_user”和“registered_user”。只要他们难以标记,你就开始获得测试代码,如“如果quentin登录,然后你看到X”,这对我来说没有任何意义。 会议是否适合装置? – 2009-06-22 07:26:35

0

我发现嘲笑authlogic对象很辛苦,我最终放弃了嘲笑。相反,我现在使用object daddy生成器方法。我的功能测试现在更加快乐。顺便说一下,shoulda + object_daddy绝对是岩石。 Shoulda的事务上下文确保我的测试数据库保持清洁,并且我不必首先模拟简单的activerecord对象。

1

在Rails 3中,UserSession的这种模拟不再起作用,因为AuthLogic的UserSession不是ActiveRecord :: Base的一个实例。修复适用于我:

class UserSession < Authlogic::Session::Base 
    extend ActiveModel::Naming 
end 
相关问题