0

私はここ数時間、このコードをテストする最良の方法を理解しようとしています。Stream.generateを使用してユニットテストメソッドを作成する方法は?

void consume() { 
    executorService.execute(() -> Stream.generate(this::takeFromQueue) 
     .filter(Optional::isPresent) 
     .map(Optional::get) 
     .forEach(messageSender::send)); 
} 

private Optional<Message> takeFromQueue() { 
    try { 
    return Optional.ofNullable(queue.take()); 
    } catch (InterruptedException e) { 
    log.error("Queue consumer interrupted."); 
    return Optional.empty(); 
    } 

}

コードの考え方は、アプリケーションが終了するまで、別のスレッドで実行されるのBlockingQueueの消費者に提供することです。 この状況では、スレッドが無限ストリームを終了するのを待っているので、executorServiceをモックできません。実行を別のスレッドで実行したままにすると、テストは確定的でなくなり、少なくともスレッドからメッセージを消費する時間を与えるためにThread.sleepに依存する必要があります。 アイデア

ありがとうございました。

+1

'Stream.generate'をテストする理由はありません、その方法は、既に十分にテストされています。 'takeFromQueue()'と 'send()'のテストケースを作ってください。単純なストリームチェーンではありません。ところで、 'take()'は 'null'を返すことはないので、' ofNullable'を使う理由はありません。あなたは事実上永遠にループしており、中断を無視しているので、 'take()'をもう一度呼び出すだけで、 'Optional'を扱う必要は全くありません。 'take()'が成功するまで 'takeFromQueue'をループすると同じ効果があります。 – Holger

+0

申し訳ありませんが、タイトルが正しいとは思いません。私はStream.generateをテストしたくないので、それを使用するコードをテストしたいと思います。私は 'takeFromQueue()'をテストするべき部分を私には与えません。それはそれほど重要ではない部分です。特に 'Optional'を削除して、永遠にループするだけです。私がテストしなければならないと思うのは、キューから取り出されたすべてのオブジェクトが 'messageSender'に送られるということです。シングルスレッドのシナリオでは、テストがキューから取り出している間にハングし、マルチスレッドの場合はシステムの速さに依存するため、基本的な方法はわかりません。 – Kilian

+0

"キューから取り出されたすべてのオブジェクトが' messageSender'に送られることをテストすることは、メソッド 'consume()'がその仕事をしていることをテストすることを意味します。したがって、Stream APIにはまったく関係ありません。しかし、無限ループを含むメソッドをテストすることは、その障害を持っています... – Holger

答えて

0

(ストリーム) を消費するようにメソッドconsume()を変更し、それを固定サイズのストリームで呼び出すことをお勧めします。消費とそれを呼び出すよりも、あなたの実際のコード(Stream.generate(本:: takeFromQueue))で

関連する問題