2017-08-13 107 views
1

我有一個類HttpClient有一個返回CompletableFuture功能:模擬CompletionException在測試

public class HttpClient { 

    public static CompletableFuture<int> getSize() { 
     CompletableFuture<int> future = ClientHelper.getResults() 
       .thenApply((searchResults) -> { 
        return searchResults.size(); 
       }); 

     return future; 
    } 
} 

然後另一個函數調用此函數:

public class Caller { 

    public static void caller() throws Exception { 
     // some other code than can throw an exception 
     HttpClient.getSize() 
     .thenApply((count) -> { 
      System.out.println(count); 
      return count; 
     }) 
     .exceptionally(ex -> { 
      System.out.println("Whoops! Something happened...."); 
     }); 
    } 
} 

現在,我想寫一個測試來模擬ClientHelper.getResults失敗,所以我寫這個:

@Test 
public void myTest() { 
    HttpClient mockClient = mock(HttpClient.class); 

    try { 
     Mockito.doThrow(new CompletionException(new Exception("HTTP call failed"))) 
       .when(mockClient) 
       .getSize(); 

     Caller.caller(); 

    } catch (Exception e) { 
     Assert.fail("Caller should not have thrown an exception!"); 
    } 
} 

此測試失敗。 exceptionally內的代碼從未得到執行。但是,如果我正常運行源代碼並且HTTP調用確實失敗,那麼它會很好地轉到exceptionally塊。

我該如何編寫測試以便執行exceptionally代碼?

回答

3

我得到這個由測試做這個工作:如果

CompletableFuture<Long> future = new CompletableFuture<>(); 
future.completeExceptionally(new Exception("HTTP call failed!")); 

Mockito.when(mockClient.getSize()) 
     .thenReturn(future); 

不知道這是雖然最佳途徑。

+2

我認爲這是最好的方法:CompletableFuture是一個廣泛使用和經過充分測試的庫,因此您可以依靠它來測試代碼,而不是嘗試使用Mockito複製其行爲。 (當然,Mockito是一個體面的方式來提供未來的系統測試中的依賴,您嘲笑。) –

+1

謝謝@JeffBowman! –