2010-08-24 144 views
108

我已經使用了這個,但沒有找到任何相關的。我有這樣的事情:Mockito。驗證方法參數

Object obj = getObject(); 
Mockeable mock= Mockito.mock(Mockeable.class); 
Mockito.when(mock.mymethod(obj)).thenReturn(null); 

Testeable obj = new Testeable(); 
obj.setMockeable(mock); 
command.runtestmethod(); 

現在,我想驗證mymethod(Object o),這就是所謂的內部runtestmethod(),被稱爲與對象o,沒有任何其他的。但我始終通過測試,無論我穿上了驗證,例如,具有:

Mockito.verify(mock.mymethod(Mockito.eq(obj))); 

Mockito.verify(mock.mymethod(Mockito.eq(null))); 

Mockito.verify(mock.mymethod(Mockito.eq("something_else"))); 

我總是通過測試。我如何完成驗證(如果可能的話)?

謝謝。

回答

40
  • 如果您不使用其他匹配器,則不需要eq匹配器。
  • 您沒有使用正確的語法 - 您的方法調用應該在.verify(mock)之外。您現在正在對方法調用的結果啓動驗證,而不驗證任何內容(不進行方法調用)。因此所有測試都通過了。

你的代碼應該是這樣的:

Mockito.verify(mock).mymethod(obj); 
Mockito.verify(mock).mymethod(null); 
Mockito.verify(mock).mymethod("something_else"); 
+0

我曾嘗試過,現在再次確定。我仍然有同樣的問題,測試總是通過。 – manolowar 2010-08-24 10:41:34

+1

那麼也許你沒有足夠的表現。這應該工作。 – Bozho 2010-08-24 10:54:03

3

你檢查的mockable類equals方法?如果這個返回值總是爲真,或者你對同一個實例測試了同一個實例,並且同等方法沒有被覆蓋(因此只針對引用進行檢查),那麼它返回true。

48

你是否試圖利用對象的.equals方法來做邏輯平等?這種利用包含在在的Mockito匹配argThat

import static org.mockito.Matchers.argThat 

接下來,你可以實現自己的參數匹配

private class ObjectEqualityArgumentMatcher<T> extends ArgumentMatcher<T> { 
    T thisObject; 

    public ObjectEqualityArgumentMatcher(T thisObject) { 
     this.thisObject = thisObject; 
    } 

    @Override 
    public boolean matches(Object argument) { 
     return thisObject.equals(argument); 
    } 
} 

現在用你的代碼,你可以將推遲到每個對象.equals方法你可以做更新閱讀...

Object obj = getObject(); 
Mockeable mock= Mockito.mock(Mockeable.class); 
Mockito.when(mock.mymethod(obj)).thenReturn(null); 

Testeable obj = new Testeable(); 
obj.setMockeable(mock); 
command.runtestmethod(); 

verify(mock).mymethod(argThat(new ObjectEqualityArgumentMatcher<Object>(obj))); 

如果你只是去精確的相等(在內存中同一個對象),只是做

verify(mock).mymethod(obj); 

這將驗證它被調用一次。

+1

您可以使用'ReflectionEquals'類中的構建來達到此目的。 – takacsot 2014-04-16 06:23:04

+2

+1爲您的答案。但是我想補充一下'verify(mock).mymethod(obj);'不檢查EXACT是否相等(內存中的同一個對象)。相反,它使用本來可能被overwridden的對象equals-method。 – efux 2015-05-20 18:32:29

+0

您也可以創建'ArgumentMatcher'的匿名實現,以減少冗長。 – botchniaque 2015-09-01 13:07:59

1

你用同一個()匹配器試過嗎?如在:

verify(mockObj).someMethod(same(specificInstance)); 

我有同樣的問題。我使用eq()匹配器以及refEq()匹配器嘗試了它,但我總是有誤報。當我使用相同的()匹配器時,當參數是不同的實例並且一旦參數是相同的實例時,測試失敗。

140

ArgumentMatcher的替代方法是ArgumentCaptor

正式例如:

ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class); 
verify(mock).doSomething(argument.capture()); 
assertEquals("John", argument.getValue().getName()); 

一個俘虜也可以使用@Captor註釋中定義:

@Captor ArgumentCaptor<Person> captor; 
//... MockitoAnnotations.initMocks(this); 
@Test public void test() { 
    //... 
    verify(mock).doSomething(captor.capture()); 
    assertEquals("John", captor.getValue().getName()); 
} 
+0

謝謝你的樣品!從未使用它。在代碼中感覺像* captor *之類的東西有點奇怪,但它有幫助。 – Artemis 2016-03-01 14:32:24

+0

哈哈,我不明白這個問題,但答案幫了我很多。感謝:-) – 2017-11-14 12:54:35

+0

重要:使用模擬調用verify()/ capture()_after_。我以爲它必須在......之前「安裝」...... – 2018-02-21 16:02:58

-1

您還可以使用TypeSafeDiagnosingMatcher

private Matcher<GetPackagesRequest> expectedPackageRequest(final AvailabilityRequest request) { 
    return new TypeSafeDiagnosingMatcher<GetPackagesRequest>() { 

     StringBuilder text = new StringBuilder(500); 

     @Override 
     protected boolean matchesSafely(GetPackagesRequest req, Description desc) { 
      String productCode = req.getPackageIds().iterator().next().getValue(); 
      if (productCode.equals(request.getSupplierProductCode())) { 
       text.append("ProductCode not equal! " + productCode + " , " + request.getSupplierProductCode()); 
       return true; 
      } 

      text.append(req.toString()); 
      return false; 
     } 

     @Override 
     public void describeTo(Description d) { 
      d.appendText(text.toString()); 
     } 
    }; 
} 

然後驗證調用:

Mockito.verify(client).getPackages(Mockito.argThat(expectedPackageRequest(request))); 
2

另一種方法是使用org.mockito.internal.matchers.Equals.Equals方法,而不是重新定義之一:

verify(myMock).myMethod((inputObject)Mockito.argThat(new Equals(inputObjectWanted))); 
0

我已經以這種方式

@UnitTest 
public class JUnitServiceTest 
{ 
    @Mock 
    private MyCustomService myCustomService; 


    @Test 
    public void testVerifyMethod() 
    { 
     Mockito.verify(myCustomService, Mockito.never()).mymethod(parameters); // method will never call (an alternative can be pick to use times(0)) 
     Mockito.verify(myCustomService, Mockito.times(2)).mymethod(parameters); // method will call for 2 times 
     Mockito.verify(myCustomService, Mockito.atLeastOnce()).mymethod(parameters); // method will call atleast 1 time 
     Mockito.verify(myCustomService, Mockito.atLeast(2)).mymethod(parameters); // method will call atleast 2 times 
     Mockito.verify(myCustomService, Mockito.atMost(3)).mymethod(parameters); // method will call at most 3 times 
     Mockito.verify(myCustomService, Mockito.only()).mymethod(parameters); // no other method called except this 
    } 
} 
使用Mockito.verify
相關問題