2014-04-11 96 views
2

即使是一個看似簡單的索引操作感覺令人難以置信的複雜,單獨進行測試。 我發現自己不得不模擬出我的幾個UserTenant方法只是通過before_filter s到獲得。然後我需要模擬出KaminariTenant#users的行動。單獨測試軌道控制器的正確方法是什麼?

這種感覺過度用於測試控制器動作無控制流程。

TDD原則,可以說,對於嘲笑過大需要的是設計不良的跡象,但我不知道我怎麼會提取此功能集成到一個域對象。

是這種痛苦的嘲諷標準測試的Rails控制器?有沒有更好的方法來做到這一點,我根本不知道?

例如,也許跳過before_filter會使這個不那麼痛苦,但因爲它們是相應的私人方法,所以我覺得跳過它們是沒有意義的。

class UsersController < AdminController 
    before_filter :check_auth 
    before_filter :check_admin 
    around_filter :set_tenant_time_zone, if: current_tenant 

    def index 
     Kaminari.paginate(current_tenant.users).page(params[:page]) 
    end 

    private 

    def current_user 
     # gets user from session 
    end 

    def current_tenant 
     current_user.tenant if current_user 
    end 

    def set_tenant_time_zone 
     Time.use_zone(current_tenant.time_zone, &block) 
    end 

    def check_auth 
     redirect_to login_url unless AuthChecker.new(current_user, request.remote_ip).has_access? 
    end 

    def check_admin 
     redirect_to root_url unless current_user.is_admin? 
    end 
    end 

回答

1

你必須做所有這些嘲笑/如果你想運行這些before_filters存根,但是我認爲,對於那些情況下,最好使用一些規範的輔助方法來創建登錄的用戶的話,上你的規格,你只需要在控制器的「之前(:每個)」塊中調用那個你想要用戶的方法。

在spec_helper.rb:

def current_user(stubs = {}) 
    unless @current_user 
    u = FactoryGirl.build(:user, stubs) 
    u.save(:validate => false) 
    @current_user = u 
    end 
    @current_user 
end 

def current_user_session(stubs = {}, user_stubs = {}) 
    @current_session ||= mock_model("Session", {:record => nil, :user => current_user(user_stubs)}.merge(stubs)) 
end 

def login(session_stubs = {}, user_stubs = {}) 
    UserSession.stub(:find).and_return(current_user_session(session_stubs, user_stubs)) 
    controller.stub(:current_user => @current_user) 
end 

這樣,在需要登錄的用戶有一些特殊的存根控制器的規格,我可以做

describe 'GET index' do 
    before(:each) do 
    login #this does all you need to pass the filters 
    end 

    it 'does something' do 
    current_user.stub(:some_method) 
    get :index 
    expect(response).to something 
    end 
end 

這樣的測試只存根,實例和行動的實際代碼的預期,而不是過濾器

+0

感謝您的輸入。我希望有一個解決方案可以幫助我簡化我的模擬,同時仍然在絕對隔離的測試中,但也許這只是一廂情願的想法。看起來控制器似乎很難孤立地進行測試。 – hangsu

相關問題