2014-04-11 3 views
2

겉으로보기에 단순한 인덱스 작업조차도 테스트 할 때 엄청나게 복잡하다고 느껴집니다. 나는 before_filter을 통과하기 위해 내 UserTenant 몇 가지 방법을 조롱해야합니다. 그런 다음 작업을 수행하려면 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

감사합니다. 나는 절대적인 고립 상태에서 테스트하면서 나의 mock을 단순화하는 데 도움이 될 수있는 해결책을 원했지만 아마도 그것은 단지 희망적인 생각 일 것입니다. 컨트롤러는 본질적으로 고립되어 테스트하기가 어렵습니다. – hangsu

관련 문제