Test Double

아래 내용은 오픈마루 루비 스터디(7/31)에서 공유하기 위해 작성한 내용입니다.

 

단위 테스트(Unit Test)?

단위테스트에 대한 오해

 

현재 개발 중인 유닛을 잘 만드는데 집중하기 위해, 다른 건 일단 잊자.

Test Double은 내 머릿속의 지우개!

 

Test Double

SUT(System Under Testing)가 의존하는 구현체의 일부를 "테스트에서만 사용하는 것"으로 바꾼다.

 

Test%20Double.gif

그림 출처: http://xunitpatterns.com/Test%20Double.html

 

 

Verification

테스트는 검증(verification)의 과정이다. 검증은 2가지 방법으로 할 수 있다.

 

 

Mock과 Stub의 차이는 어떤 검증 방법의 차이.

 

TDD 고전주의자

왠만하면 실제 객체를 그냥 사용하자. 불가피한 경우(ex. 네트워크 통신)는 스텁을 만든다.

 

아래는 acts_as_cached_test.rb. ActsAsCached의 일부를 스텁으로 대체한다.

 

  1. class CacheCache < Hash
      def setted?(name)
        not self[:set][name].nil?
      end
    end

    $cache_cache = CacheCache.new

    module ActsAsCached
      module Disabled
        def set_cache_with_disabled(*args)
          key = cache_key(args.first)#.tap{|x| p x}
          $cache_cache[:set][key] = args[1]
          args[1]
        end
      end
    end

 

그리고 상태를 검증한다.

 

  1. it "should cache tag_list" do
      @note.tag_list(@user)
      cache_store.should be_setted("Note:4:tag_list")
    end

 

TDD 뫅주의자

뭔가 특별한 행위를 하는 객체가 있다면 항상 mock을 사용한다.

 

  1.   it "should refresh recent pages cache" do
        flexmock(Page).should_receive(:set_cache).once.
          with('/recent_pages/7/ko', any, any).and_return []
       
        get :recent_pages, :id => 7, :refresh => true, :lang => 'ko'
      end

 

여기서 좀 더 발전하면, 객체들의 행위들을 잘 관찰하고, 검증하면 개발을 잘 할 수 있다고 믿는 BDD(행위 주도 개발)에 다다른다. BDD는 TDD의 용어를 행위 중심으로 개정한 뫅주의자들의 작품이다.

 

고전주의자 vs. 뫅주의자

양쪽 모두 자신들의 논지가 있다. 하지만 뫅주의자들이 설득의 필요를 더 느끼므로 이 쪽 논리가 더 발전되어 있다. 고씨와 뫅씨의 대화를 들어보자.

 

 

이 논쟁을 마치려면 손석희씨가 필요할 것 같다. 좀 더 잘 정리된 문서를 원하면 Mocks Aren't Stubs을 읽어보도록.