2013-08-20 15 views
1

好吧,所以我的主要問題是我已經實現了Mailboxer到我們的項目中來處理消息傳遞,並且我正在爲它編寫測試。但是,我一直在一次又一次地磕磕絆絆。我嘗試了幾個不同的存根/嘲笑,但沒有取得任何進展。Rails在過濾器之前設置實例變量的測試控制器方法

我們有一個conversations_controller.rb依賴於before_filters來設置執行每個操作所需的所有實例變量。然後在控制器操作中,直接引用實例變量以執行任何操作或返回特定數據。

這裏是我們的索引行爲的一個例子,它返回的「盒子」,也就是在before_filter,來指定的所有對話,郵箱在另外的before_filter還指定了:前置過濾器

class ConversationsController < ::ApplicationController 
    before_filter :get_user_mailbox, only: [:index, :new_message, :show_message, :mark_as_read, :mark_as_unread, :create_message, :reply_message, :update, :destroy_message, :untrash] 
    before_filter :get_box 

    def index 
     if @box.eql? "inbox" 
     @conversations = @mailbox.inbox 
     elsif @box.eql? "sentbox" 
     @conversations = @mailbox.sentbox 
     else 
     @conversations = @mailbox.trash 
     end 
    end 

和:

private 
def get_user_mailbox 
    @user = User.where(:user_name => user.user_name.downcase).where(:email => user.email.downcase).first_or_create 
    @mailbox = @user.mailbox if @user 
end 

def get_box 
    if params[:box].blank? or !["inbox","sentbox","trash"].include?params[:box] 
     params[:box] = 'inbox' 
    end 
    @box = params[:box] 
end 

所以我想我有一個問題2。首先,如何讓我的測試生成索引操作所需的正確數據@mailbox,@user和@box。接下來,我如何傳遞假參數來將@box設置爲不同的「inbox/sentbox/trash」。我已經嘗試過controller.index({box:「inbox」}),但總是得到「0的錯誤參數1」消息。

我嘗試了以下各種不同的方式,但總是得到零:類錯誤,這意味着我的實例變量肯定沒有正確設置。

describe "GET 'index' returns correct mailbox box" do 
    before :each do 
    @user = User.where(:user_name => 'test').where(:email => '[email protected]').first_or_create 
    @mailbox = @user.mailbox 
    end 

    it "#index returns inbox when box = 'inbox'" do 
    mock_model User 
    User.stub_chain(:where, :where).and_return(@user) 
    controller.index.should == @mailbox.inbox 
    end 
end 

回答

0

過濾器和回調很難測試和調試。儘可能避免使用它們。

在這種情況下,我不認爲你的before_filter是必要的,因此不需要測試它。模型更好的方法之家。

檢查我refacoring:

class User < ActiveRecord::Base 
    delegate :inbox, :sentbox, :trash, to: :mailbox 
end 

class ConversationsController < ::ApplicationController 
    def index 
    @conversations = current_user.send get_box 
    end 

    private 
    def get_box 
    # your code 
    end 
end 

這就是全部。應該夠了。

然後您可以定期進行測試。

+0

感謝您的留言。這是一個非常不錯的解決方案。我還沒有嘗試過的主要原因是因爲我們的郵箱實現實際上並沒有生成郵箱模型。如果它確實在某個地方生成它,出於某種原因我找不到它。我可能完全錯誤,但我認爲Mailboxer通過SQL調用來處理郵箱,消息等等,使用了大量的直接數據庫交互。在這種情況下,我唯一可以輕鬆更改的模型就是User。 但正如我所說,我可以完全關閉,只需要深入Mailboxer。 – Nightsurge

+0

@Nightsurge,模型方法可能在gem中,然後包含在用戶模型中(如果找不到它)。但是有沒有郵箱模型並不重要。看,你已經有'user.mailbox'和'user.mailbox.inbox'工作。如果沒有模型,你可以直接定義方法而不是使用'委託'。例如'def收件箱; mailbox.inbox;結束「,然後將其用於控制​​器中作爲答案。希望有所幫助。 –

0

首先,閱讀rails testing的官方文檔:使用數據進行測試,並使用passing parameters to controlers進行說明。

要爲你的測試,你可以將數據:

  1. 填補一些郵箱和用戶測試數據庫使用軌道固定裝置或使用類似工廠女孩

  2. 使用模擬對象的假數據。我個人使用的摩卡寶石,但也有其他

我傾向於使用兩者的結合,在可能的情況prefering mock對象和嘲諷時需要太多的代碼回落至工廠女孩。

相關問題