2012-08-03 74 views
39

我正在使用Mockito 1.9.0。我將如何驗證一個方法只被調用一次,並且傳遞給它的某個字段包含某個值?在我的JUnit測試,我有使用Mockito,我該如何驗證某個方法是否被某個參數調用?

@Before 
public void setupMainProg() { 
    // Initialize m_orderSvc, m_opportunitySvc, m_myprojectOrgSvc 
    ... 
    m_prog = new ProcessOrdersWorker(m_orderSvc, m_opportunitySvc, m_myprojectOrgSvc); 
} // setupMainProg 

@Test 
public void testItAll() throws GeneralSecurityException, IOException { 
    m_prog.work(); 
} 

的方法「工作」要求「m_orderSvc」的方法(在傳遞給對象一個參數)。 「m_orderSvc」又包含一個成員字段「m_contractsDao」。我想驗證一下「m_contractsDao.save」被調用了一次,並且傳遞給它的參數包含一個特定的值。

這可能有點混亂。讓我知道我如何澄清我的問題,我很樂意這樣做。

回答

48

首先,您需要創建一個模擬m_contractsDao並進行設置。假設班級是ContractsDao:

ContractsDao mock_contractsDao = mock(ContractsDao.class); 
when(mock_contractsDao.save(any(String.class))).thenReturn("Some result"); 

然後將模擬注入m_orderSvc並調用您的方法。

m_orderSvc.m_contractsDao = mock_contractsDao; 
m_prog = new ProcessOrdersWorker(m_orderSvc, m_opportunitySvc, m_myprojectOrgSvc); 
m_prog.work(); 

最後,驗證模擬被正確地稱爲:

verify(mock_contractsDao, times(1)).save("Parameter I'm expecting"); 
+9

僅供參考,你可以離開過',時間(1)',因爲它總是暗示,除非你添加一個量詞指定比只有一個時間以外的東西。而不是'any(String.class)',有一​​個更方便的'anyString()'。 – 2012-08-03 21:08:18

+3

值得注意的是,傳遞給AFTER'verify'方法的參數是用'equals'與實際測試期間傳遞的參數進行比較的。所以,不管是什麼方法(在mamboking的例子中是'save'方法),想一想每個參數的_type_,以及與'equals'的比較是否是你真正想要的。如果你想要用「equals」之外的東西來測試參數,你需要一個「ArgumentMatcher」(這可能是Kevin Welker的答案中的「ArgumentCaptor」)。 – 2012-08-05 05:45:54

+0

你如何指定一次,而不是兩次或更多? @ KevinWelker的評論說這是隱含的,但不確定它是否意味着一次,或者至少一次。 – aliteralmind 2015-06-19 18:53:19

21

大廈關閉Mamboking的回答:

ContractsDao mock_contractsDao = mock(ContractsDao.class); 
when(mock_contractsDao.save(anyString())).thenReturn("Some result"); 

m_orderSvc.m_contractsDao = mock_contractsDao; 
m_prog = new ProcessOrdersWorker(m_orderSvc, m_opportunitySvc, m_myprojectOrgSvc); 
m_prog.work(); 

解決您的要求,以驗證參數是否包含一定值,我可以假設你的意思是該參數是一個字符串,你想測試一下String參數是否包含一個子字符串。爲此,你可以這樣做:

ArgumentCaptor<String> savedCaptor = ArgumentCaptor.forClass(String.class); 
verify(mock_contractsDao).save(savedCaptor.capture()); 
assertTrue(savedCaptor.getValue().contains("substring I want to find"); 

如果這種假設是錯誤的,參數save()是某種形式的集合,那也只能是略有不同:

ArgumentCaptor<Collection<MyType>> savedCaptor = ArgumentCaptor.forClass(Collection.class); 
verify(mock_contractsDao).save(savedCaptor.capture()); 
assertTrue(savedCaptor.getValue().contains(someMyTypeElementToFindInCollection); 

您還可以檢查到ArgumentMatchers,如果你知道如何使用Hamcrest匹配器。

7

這是更好的解決方案:

verify(mock_contractsDao, times(1)).save(Mockito.eq("Parameter I'm expecting")); 
+0

這樣比較好當你在處理非原始類型時。 – pisaruk 2017-03-03 22:37:01

相關問題