Using Mockito, how do I verify a method was a called with a certain argument?
JavaMockingMockitoJava Problem Overview
I'm using Mockito 1.9.0. How would i verify that a method got called exactly once, and that one of the fields passed to it contained a certain value? In my JUnit test, I have
@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();
}
The method "work" calls a method of "m_orderSvc" (one of the arguments passed in to the object). "m_orderSvc," in turn contains a member field, "m_contractsDao". I want to verify that "m_contractsDao.save" got called exactly once and that the argument passed to it contains a certain value.
This may be a little confusing. Let me know how I can clarify my question and I'm happy to do so.
Java Solutions
Solution 1 - Java
First you need to create a mock m_contractsDao and set it up. Assuming that the class is ContractsDao:
ContractsDao mock_contractsDao = mock(ContractsDao.class);
when(mock_contractsDao.save(any(String.class))).thenReturn("Some result");
Then inject the mock into m_orderSvc and call your method.
m_orderSvc.m_contractsDao = mock_contractsDao;
m_prog = new ProcessOrdersWorker(m_orderSvc, m_opportunitySvc, m_myprojectOrgSvc);
m_prog.work();
Finally, verify that the mock was called properly:
verify(mock_contractsDao, times(1)).save("Parameter I'm expecting");
Solution 2 - Java
Building off of Mamboking's answer:
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();
Addressing your request to verify whether the argument contains a certain value, I could assume you mean that the argument is a String and you want to test whether the String argument contains a substring. For this you could do:
ArgumentCaptor<String> savedCaptor = ArgumentCaptor.forClass(String.class);
verify(mock_contractsDao).save(savedCaptor.capture());
assertTrue(savedCaptor.getValue().contains("substring I want to find");
If that assumption was wrong, and the argument to save()
is a collection of some kind, it would be only slightly different:
ArgumentCaptor<Collection<MyType>> savedCaptor = ArgumentCaptor.forClass(Collection.class);
verify(mock_contractsDao).save(savedCaptor.capture());
assertTrue(savedCaptor.getValue().contains(someMyTypeElementToFindInCollection);
You might also check into ArgumentMatchers, if you know how to use Hamcrest matchers.
Solution 3 - Java
This is the better solution:
verify(mock_contractsDao, times(1)).save(Mockito.eq("Parameter I'm expecting"));