본문 바로가기

Backend/TDD

Test Double이란? Mock, Spy, Stub, Dummy

“Mock is a kind of spy, a spy is a kind of stub, and a stub is a kind of dummy” 
Mock < Spy < Stub < Dummy

 

📝 Test Double (= Mock) 이란?
  • 일반적으로 테스트에 사용되는 모든 테스트 객체들을 의미한다. (이 때의 Mock = Test Double)

Test Double 종류

 

  • Dummy
    목적 : 사용 방법에 신경쓰지 않고 무언가를 전달할때 사용
    → 테스트를 통과하기 위해 특정 인자가 필수로 필요하다고 가정할 때 사용(그렇지만 그 인자가 사용되지는 않을 때)
    • dummy는 return 값이 있는 것이 좋음 (dummy를 사용하려 할때 NullPointerException이 뜰 수 있으므로)
        // dummy example
        public class DummyAuthorizer implements Authorizer {
            public Boolean authorize(String username, String password) {
                return null;
            }
        }

 

  • Stub

목적 : 이미 테스트를 성공한 기능에 대해서는 성공임을 가정하고, 다른 핵심 기능을 테스트 할 수 있도록 함

  • 기존의 것을 함께 테스트하게 된다면
    • 시간이 오래 걸림(세팅 시간 포함)
    • 기존 기능에 버그가 있다면 테스트가 실패하게 됨
    • 불필요한 결합력(unnecessary coupling)
   // stub example 
    public class AcceptingAuthorizerStub implements Authorizer {
        public Boolean authorize(String username, String password) {
            return true; //핵심
        }
    }

 

  • Spy

목적 : 특정 메서드가 시스템 내에서 호출되는지를 확인하고 싶을 때

  • 호출 횟수 계산 가능, 전달된 인자 리스트 확인 가능 ** 많이 사용하게 된다면 coupling이 늘어나게됨 → fragile test

** fragile test : 실패하지 않아야할 곳에서 실패하는 테스트 (다른 테스트에서 코드 수정을 하게 된다면 실패하는 테스트)

    //spy example
    public class AcceptingAuthorizerSpy implements Authorizer {
        public boolean authorizeWasCalled = false;

        public Boolean authorize(String username, String password) {
            authorizeWasCalled = true; //호출 됐는지 체크
            return true;
        }
    }

 

  • True Mock

목적 : 행동을 테스트. return 값에 대해 관심 없음. ‘어떤 함수가 어떤 인자와 함께 언제 어떻게 호출되었는지’에 중점. 기대값을 가지고 있음

  • JMock, or EasyMock, or Mockito를 통해 쉽고 빠르게 제작 가능
    //true mock example
    public class AcceptingAuthorizerVerificationMock implements Authorizer {
        public boolean authorizeWasCalled = false;

        public Boolean authorize(String username, String password) {
            authorizeWasCalled = true;
            return true;
        }

        public boolean verify() {
            return authorizedWasCalled;
        }
    }

 

  • Fakes

목적 : 실제 비즈니스 로직을 가지고 있음(다른 test double 과의 차이점)

  •  기능 레벨에서 동작 다른 데이터를 통해 다른 정보를 이끌어 낼 수 있음(like simulator)
    //fakes example
    public class AcceptingAuthorizerFake implements Authorizer {
        public Boolean authorize(String username, String password) {
            return username.equals("Bob");
        }
    }

 

 

 

 


엉클밥(Robert C. Martin)님의 The Little Mocker를 한글 요악한 포스트입니다.
http://blog.cleancoder.com/uncle-bob/2014/05/14/TheLittleMocker.html

 

Clean Coder Blog

The Little Mocker 14 May 2014 The following is a conversation around mocking: What is this?: interface Authorizer { public Boolean authorize(String username, String password); } >_An interface._ So what then, is this? public class DummyAuthorizer implement

blog.cleancoder.com