2016-08-21 13 views
1

私はJavaでテストを書くのが初めてで、クラスのメソッドが呼び出されたかどうかをテストできないようです。Mockito - クラスのメソッドが呼び出されたかどうかをテストします。

私はdatadogにメトリックを送信しており、別のクラスの関数が呼び出された場合にコード内でテストしたいと考えています。

私は最初に嘲笑する必要があると言いますが、それを動作させることはできませんでした。

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(この現在の構成では)は、新しいインスタンスをモックするための装備がありません。すべての正直なところ、この設定ではテストがより簡単になり、クライアントは1つの領域にのみ設定する必要があります。

@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

あなたは私が既に持っているコンストラクタに加えて、このコンストラクタパターンを使用することをお勧めですか?私はこれが技術的にはうまくいくと思っています....私が作らなければならない他の変更は、public final static StatsDClientメトリクスをprivate static StatsDClientメトリックに変更することです...これは、recorder.metricsをテストするために公開されなければならず、どちらか。 –

0

ここでは間違っています。 模擬フレームワークを使用して、「テスト中のクラス」をテストしないでください。

模擬フレームワークを使用して模擬オブジェクトを作成します。テストケース内の "テスト中のクラス"に渡します。そして、あなたの "テスト対象のコード"はモックされたオブジェクトのメソッドを呼び出します。戻り値を制御することによって(またはあなたのモックに何が起こるかを検証することによって)それはあなたのテストケースを書く方法です。

したがって、MetricRecorderのテストケースはMetricRecorderをモックしません。 StatsDClientクラスをモックする必要があります。マコトが示唆するように、 依存性注入を使用して、そのクラスのオブジェクトをMetricRecorderに配置します。

その他:基本的に「テスト可能な」コードを書くことは、実践する必要があるものです。あなたがこのビジネスに真剣に取り組んでいるのであれば、私は全力でこれらを見ることをお勧めしますvideos。それらのすべて。本当に(毎秒の価値がある!)。

関連する問題