2016-08-21 2 views
1

java로 테스트를 작성하는 데있어서 새로운데, 클래스의 메소드가 호출되는지 테스트 할 수없는 것처럼 보입니다.Mockito - 클래스의 메소드가 호출되는지 테스트합니다.

데이터 막에 메트릭을 보내고 다른 클래스의 함수가 호출 된 경우 코드에서 테스트하려고합니다.

우선 내가 조롱 할 필요가 있다고 말하지만 작동시키지 못한다고합니다.

MetricRecorder.java

import com.timgroup.statsd.StatsDClient; 
import com.timgroup.statsd.NonBlockingStatsDClient; 
import com.google.common.base.Preconditions; 

public class MetricRecorder { 
    private final String namespace; 
    private final static StatsDClient metrics = new NonBlockingStatsDClient(
     "my.prefix",       
     "localhost",       
     8125,         
     new String[] {"tag:value"} 
    ); 

    public MetricRecorder(String namespace) { 
     Preconditions.checkNotNull(namespace); 
     this.namespace = namespace; 
    } 

    public void inc(String metricName) { 
     this.inc(metricName, 1); 
    } 

    public void inc(final String metricName, final long value) { 
     Preconditions.checkNotNull(metricName); 
     try { 
      metrics.recordHistogramValue(MetricRecorder.name(namespace, metricName), value); 
     } catch (Exception e) { 
      logger.warn("Unable to record metric {} due to :", metricName, e); 
     } 
    } 
    ... 
} 

MetricRecorderTest.java

public class MetricsRecorderTest { 

    @Test 
    public void metricsRecorderTest() { 
     MetricRecorder recorder = new MetricRecorder("dev"); 
     recorder.inc("foo", 1); 
     verify(recorder.metrics, times(1)).recordHistogramValue(eq("dev.foo"), 1); 
    } 
} 

내가 테스트를 실행하면 나는이 => org.mockito.exceptions.misusing.NotAMockException 얻을 : (확인 통과 인수를)는 NonBlockingStatsDClient 유형이며 모의가 아닙니다!

recordHistogramValue가 호출 된 경우 어떻게 테스트해야하는지, 그리고 그렇다면 어떤 인수를 사용합니까?

답변

1

StatsDClient이 어떤 종류의 인터페이스 인 것처럼 보이기 때문에이 종속성을 개체에 주입하기가 쉽습니다. Spring이나 Guice와 같은 IoC 컨테이너를 사용하지 않더라도 생성자를 통해 인스턴스를 전달함으로써 이것을 다소 제어 할 수 있습니다.

public MetricRecorder(String namespace, StatsDClient client) { 
    Preconditions.checkNotNull(namespace); 
    Preconditions.checkNotNull(client); 
    this.namespace = namespace; 
    this.client = client; 
} 

이렇게하면 테스트 중에 전달 된 객체를 모의하기 만하면되므로 테스트가 더 간단 해집니다.

지금은 실패한 이유는 사용자가 new 인스턴스를 사용하고 있기 때문입니다.이 현재 구성에서 Mockito는 새 인스턴스를 조롱 할 준비가되어 있지 않습니다. 정직하게 말하자면,이 설정을 통해 테스트가 더 간단 해지고 클라이언트를 한 영역에서만 구성해야합니다.

@RunWith(MockitoJUnitRunner.class) 
public class MetricsRecorderTest { 

    @Test 
    public void metricsRecorderTest() { 
     StatsDClient dClientMock = Mockito.mock(StatsDClient.class); 
     MetricRecorder recorder = new MetricRecorder("dev", dClientMock); 
     recorder.inc("foo", 1); 
     verify(recorder.metrics).recordHistogramValue(eq("dev.foo"), 1); 
    } 
} 
+0

이미 가지고있는 생성자 외에도이 생성자 패턴을 사용 하시겠습니까? 나는 이것이 기술적으로 효과가있을 것이라고 생각한다 ... 단지 다른 변경은 공공 정적 정적 StatsDClient 메트릭스를 개인 정적 StatsDClient 메트릭으로한다. 그것은 recorder.metrics를 테스트하기 위해 public이어야하며 final 일 수 없다. 어느 한 쪽. –

0

여기에 문제가 있습니다. 프레임 워크를 조롱하여 "테스트중인 클래스"를 테스트하지 마십시오.

조롱 프레임 워크를 사용하여 을 조롱 한 개체를 만듭니다. 그런 다음 테스트 케이스 내에서 "테스트중인 클래스"에 전달합니다. 그런 다음 "테스트중인 코드"는 조롱 된 객체의 메소드를 호출합니다. 반환 된 값을 제어함으로써 (또는 당신의 모의 (mock)에 일어나는 일을 검증함으로써); 그것이 당신이 테스트 케이스를 작성하는 방법입니다.

따라서 MetricRecorder 용 테스트 사례는 MetricRecorder를 모의하지 않습니다. 그것은 StatsDClient 클래스를 조롱해야한다; Makoto가 제안한대로. 종속성 주입을 사용하여 해당 클래스의 오브젝트를 MetricRecorder에 넣으십시오.

기본적으로 "테스트 가능한"코드를 작성하는 것은 연습해야하는 것입니다. 나는이 사업에 진지하게 진지한다면 진심으로이 videos을 지켜 볼 것을 권고합니다. 그들 모두; 정말 (초당 가치!).

관련 문제