2016-10-04 8 views
2

私はJavaとMockitoを使って単体テストのいくつかの方法を模擬しています。例外がスローされたときに送信されるログメッセージをテストできるように、以下のコードでプロデューサを模擬したいと思います。私は未来を模倣しようとしましたが、future.get()メソッドを嘲笑することはできず、RecordMetadataクラスは最終的なものであり、嘲笑されないというエラーが発生します。どんな助けでも大歓迎です。例外を投げる未来を返すメソッドを模倣する

下の例のプロデューサは、KafkaProducerです。

public void send(Log log){ 
    Future<RecordMetadata> future = producer.send(new ProducerRecord<(this.topic, record)); 
    try { 
    RecordMetadata recordMetadata = send.get(); 
    } catch (InterruptedException e) { 
    LOG.error("Sending the message to kafka was interrupted. "+e); 
    } 
} 

答えて

3

カフカは、テスト用にクラスに注入できるMockProducerクラスを提供しています。 JUnit @Before-annotated setupメソッドで、クラス内のproducerMockProducerのインスタンスに設定できます。 MockProducerの参照先のドキュメントから:

カフカを使用するコードをテストするために使用できるプロデューサインターフェイスのモック。

デフォルトでは、このモックは各送信呼び出しを同期して正常に完了します。ただし、ユーザーがコールの完了を制御し、プロデューサがスローするためのオプションのエラーを提供できるように構成できます。

#errorNextメソッドを使用して、テストシナリオに含める例外を指定できます。

+0

ありがとう、それはうまくいきました。 errorNextは、sendメソッドが投げることができる2つのタイプの例外(InterruptedException)のうちの1つをスローすることはできません。 – annedroiid

+0

RuntimeException型の例外を指定することができます。これは、InterruptedExceptionが拡張するものです –

1

テストコードを見ずにここで正確にするのは難しいです。 2つの問題

1)RecordMetadataはMockitoモックでは使用できません。これはMockitoの既知の制限です。代わりに、publicコンストラクタを使用して、RecordMetadataの仮のインスタンスを作成できます。

2)KockkaProducerはMockitoでモックできますが、2段階アプローチが必要です。最初に、モックKafkaProducerは未来を返します。そして、第二に未来もある既知の価値を返すモックです。

public class ServiceTest { 

    @Mock 
    private KafkaProducer<String, Integer> producer; 
    @Mock 
    private Future<RecordMetadata> future; 

    @Before 
    public void setup() { 
     MockitoAnnotations.initMocks(this); 
    } 

    @Test 
    public void success() throws Exception { 
     RecordMetadata dummyRecord = new RecordMetadata(null, 0L, 0L, 0L, 0L, 0, 0); 
     when(producer.send(any())).thenReturn(future); 
     when(future.get()).thenReturn(dummyRecord); 

     producer.send(null); 
    } 

    @Test 
    public void timeout() throws Exception { 
     when(producer.send(any())).thenReturn(future); 
     when(future.get()).thenThrow(new TimeoutException("timeout")); 

     producer.send(null); 
    } 
} 
関連する問題