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に依存する必要があります。 アイデア
ありがとうございました。
'Stream.generate'をテストする理由はありません、その方法は、既に十分にテストされています。 'takeFromQueue()'と 'send()'のテストケースを作ってください。単純なストリームチェーンではありません。ところで、 'take()'は 'null'を返すことはないので、' ofNullable'を使う理由はありません。あなたは事実上永遠にループしており、中断を無視しているので、 'take()'をもう一度呼び出すだけで、 'Optional'を扱う必要は全くありません。 'take()'が成功するまで 'takeFromQueue'をループすると同じ効果があります。 – Holger
申し訳ありませんが、タイトルが正しいとは思いません。私はStream.generateをテストしたくないので、それを使用するコードをテストしたいと思います。私は 'takeFromQueue()'をテストするべき部分を私には与えません。それはそれほど重要ではない部分です。特に 'Optional'を削除して、永遠にループするだけです。私がテストしなければならないと思うのは、キューから取り出されたすべてのオブジェクトが 'messageSender'に送られるということです。シングルスレッドのシナリオでは、テストがキューから取り出している間にハングし、マルチスレッドの場合はシステムの速さに依存するため、基本的な方法はわかりません。 – Kilian
"キューから取り出されたすべてのオブジェクトが' messageSender'に送られることをテストすることは、メソッド 'consume()'がその仕事をしていることをテストすることを意味します。したがって、Stream APIにはまったく関係ありません。しかし、無限ループを含むメソッドをテストすることは、その障害を持っています... – Holger