2009-06-22 93 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 
相關問題