2017-01-04 31 views
3

我想測試下面的方法:的Mockito驗證特定的拉姆達已經作爲參數在模擬的方法已通過

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

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

} 

MessageHandler是一個輔助類,將接受該形式的功能接口實現lambda,並將其存儲以供稍後執行。

有沒有辦法用的Mockito驗證嘲笑MessageHandlerdispatchMessage方法被調用與特定lambda表達式:

意思,我可以寫這樣一個測試:

 @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] 

實際調用具有不同的參數:

..........Lambda$27/[email protected] 

這是有意義的,因爲嘗試的Mockito比較功能接口的兩種不同的實現,其具有不同的散列碼。

所以有一些其他的方式來驗證方法dispatchMessage()已經調用返回void並具有 dispatcher.dispatch("activityId", "ctxId", 1l,);體方法的拉姆達?

回答

4

是的,你可以。這裏的訣竅是你必須到達傳遞給registerMessage的lambda的實例,然後執行該表達式,然後可以驗證結果。

爲我創造了這個Handler類,包含dispatchMessage一個有意義的例子的目的是要測試:

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 
     } 
    } 
} 

你必須記住的是,lambda表達式只是一個短暫的手形來將一個函數傳遞給一個方法。在這個例子中,函數是Runnablerun方法。因此,MessageHandler接口的方法registerMessage採用Runnable作爲參數。 我還包含Dispatcher的實現,該實現從registerMessage內調用。 這樣做的測試是這樣的:

@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的第一驗證使用lambda表達式的ArgumentCaptor。在驗證之後,我們可以從捕獲器中檢索lambda表達式。 lambda表達式的類型爲Runnable,如MessageHandler接口中所定義。因此,我們可以調用其上的run方法,然後驗證Dispatcher上的dispatch方法是使用所有適當的參數調用的。

+0

這正是我想到的。 謝謝你的時間。 – JavaSloth