2017-01-04 6 views
3

が、私は次のメソッドをテストしたい特定のラムダは、モックのメソッドに引数として渡されていることを確認しますラムダを実行し、後で実行するために保存します。Mockitoは

嘲笑MessageHandlerdispatchMessage方法は、特定のラムダ式と呼ばれていることをmockitoを検証する方法があります:

 @Test 
public void testDispatchMessage_Success() throws Exception { 

    myMessageDispatcher.dispatchMessage(handler, "activityId", "ctxId", 1l,); 

    verify(handler, times(1)).dispatchMessage(() -> { 
     dispatcher 
      .dispatch("activityId", "ctxId", 1l,); 
    }); 

} 

} 

この:

意味では、私はそのようなテストを書くことができますテストでアサーションエラーが発生する: 引数が異なる!募集:

......Tests$$Lambda$28/[email protected] 

実際の呼び出しが異なる引数を有する:

mockitoは異なるハッシュコードを有する機能インターフェースの二つの異なる実装を、比較しようとするので、理にかなって
..........Lambda$27/[email protected] 

dispatchMessage()がvoidを返すラムダで呼び出され、bodyメソッドが dispatcher.dispatch("activityId", "ctxId", 1l,);であることを確認する別の方法がありますか?

答えて

4

はい、できます。ここでのトリックは、registerMessageに渡されたラムダのインスタンスに到達してからその式を実行し、その結果を検証できることです。意味のある例の目的のために

私はあなたがテストしたいdispatchMessageが含まれています。このHandlerクラス作成:何あなたが覚えていることは、ラムダ式はちょうど短い手の形であるということです

public class Handler { 

    private Dispatcher dispatcher = new Dispatcher(); 

    public void dispatchMessage(MessageHandler handler, String argument1, String argument2, Long argument3) { 

     handler.registerMessage(() -> { 
      dispatcher.dispatch(argument1, 
        argument2, 
        argument3); 
     }); 

    } 

    interface MessageHandler { 
     void registerMessage(Runnable run); 
    } 

    static class Dispatcher { 
     void dispatch(String a, String b, long c){ 
      // Do dispatch 
     } 
    } 
} 

を関数にメソッドを渡します。この例では、関数はRunnablerunメソッドです。したがって、MessageHandlerのインタフェースのregisterMessageメソッドは、引数としてRunnableを受け取ります。 またregisterMessageから呼び出されるDispatcherの実装も含まれています。 このためのテストは、次のようになります。

@RunWith(MockitoJUnitRunner.class) 
public class HandlerTest { 
    @Mock 
    private Dispatcher dispatcher; 
    @InjectMocks 
    private Handler classUnderTest; 
    @Captor 
    private ArgumentCaptor<Runnable> registerMessageLambdaCaptor; 

    @Test 
    public void shouldCallDispatchMethod() { 
     final String a = "foo"; 
     final String b = "bar"; 
     final long c = 42L; 

     MessageHandler handler = mock(MessageHandler.class); 

     classUnderTest.dispatchMessage(handler, a, b, c); 

     verify(handler).registerMessage(registerMessageLambdaCaptor.capture()); 

     Runnable lambda = registerMessageLambdaCaptor.getValue(); 

     lambda.run(); 

     verify(dispatcher).dispatch(a, b, c); 
    } 
} 

たちがregisterMessageの最初の検証に使用ラムダ式のためArgumentCaptorがあります。その検証の後、ラムダ式をキャプチャから取り出すことができます。ラムダ式のタイプは、MessageHandlerインターフェースで定義されているように、Runnableです。したがって、runメソッドを呼び出して、Dispatcherdispatchメソッドがすべての適切な引数で呼び出されたことを確認できます。

+0

これはまさに私が心に留めていたことです。 ありがとうございます。 – JavaSloth