2017-06-24 10 views
0

Java 8のFire-and-forget完了ステージメソッドを含むメソッドを含む統合テストを作成しようとしています。次Java 8での非同期のfire-and-forgetメソッドのテスト

public CompletionStage<User> createAndStoreUser() { 
    return createUser() 
      .thenApply(this::store) 
      .thenApply(user -> { 
       findTeam(user) 
        .thenAccept(team -> { // fire and forget 
         thirdPartyClient.enqueue(team); 
        }) 
        .handle(swallow(t -> log.error("Enqueue team failed", t))); 
       return user; 
      }) 
    }) 

現在、私の統合テストは、次のようになります。

@Test 
public void testCreateAndStoreUser() { 
    User user = createAndStoreUser().toCompletableFuture().join(); 

    ItThirdPartyClient thirdPartyClient = itThirdPartyClient(); 
    assertThat(thirdPartyClient.getQueue(), hasSize(1)); 
} 

しかし、エンキュー呼び出しが別のスレッドであるとで完了していない可能性があるため、これは毎回合格する保証はありませんアサーションが行われる時間。入れ子にされたCompletionStageをテスト目的のためだけに完成させるように強制する方法はありますか?

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

答えて

0

多くのオプションとあなたが非同期結果を主張する前に、テストメソッドを完了し、結果やより良いと言うために、「待ち」の平均スレッドを避けるために使用できるライブラリがあります。

  • あなたが使用している場合は、 Java Futuresでは、ブロッキングメソッドを使用して、未来が完了するまでメインスレッドをブロックすることができます。これは永遠にブロックできることに注意してください。
  • 非同期メソッドにExecutorを提供できる場合は、単体テストで同期Executorを使用し、実動コードで非同期エグゼキュータを使用できます。あなたがテストするために、いくつかのライブラリを使用することができる一方で
  • この
    • 最初と簡単に解決策は、使用されたCountDownLatchですが、非常に早いあなたがメインスレッドにあなたの非同期スレッドからのassert結果を返すようにしようとすると、エラーを発見します。
    • 私の選択は、もう一つの良いオプションは、あなたがここにいくつかの例https://github.com/playframework/play-java-ebean-example/blob/2.6.x/test/ModelTest.java
を見ることができます https://github.com/awaitility/awaitilityで非常に良い説明が https://github.com/playframework/play-java-ebean-example/blob/2.6.x/test/ModelTest.java
  • ここで見つけることができます同時ユニットhttps://github.com/jhalterman/concurrentunitです
  • 関連する問題