81

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.

bric3
42.7k9 gold badges99 silver badges116 bronze badges
asked Aug 3, 2012 at 20:25

3 Answers 3

79

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");
answered Aug 3, 2012 at 21:00
Sign up to request clarification or add additional context in comments.

8 Comments

FYI, you could leave off , times(1), as it is always implied unless you add a quantifier specifying something other than exactly one-time. And instead of any(String.class), there is a slightly more convenient anyString().
It's also worth noting that the argument that's passed to the method AFTER verify is compared using equals to the argument that was passed during the actual test. So, whatever the method is (the save method in mamboking's example), think about the type of each parameter, and whether a comparison with equals is what you actually want. If you want the argument to be tested with something other than equals, you'll need an ArgumentMatcher of some kind (which might be an ArgumentCaptor as in Kevin Welker's answer).
How do you specify exactly once, not two or more? @KevinWelker's comment says it's implicit, but not sure if it means exactly once, or at least once.
Rather than passing the exact argument that I expect, is there a way to instead pass a predicate over possible arguments that could be passed to the method? E.g. verify(mock_contractsDao, times(1)).save((String s) -> s.length() == 23);?
Also I haven't tried anything in Mockito 2.x yet, but you might find what you want in the new ArgumentMatcher. This syntax may not be right, but the following may be close to what you want under Mockito 2.x: verify(mock_contractsDao).save(argThat(s->s.length==23));
|
32

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.

Jaymes Bearden
2,0492 gold badges21 silver badges25 bronze badges
answered Aug 3, 2012 at 21:25

Comments

21

This is the better solution:

verify(mock_contractsDao, times(1)).save(Mockito.eq("Parameter I'm expecting"));
answered Apr 18, 2016 at 7:46

2 Comments

This is better when you are dealing with non primitive types.
this works too also you have to use eq() if you have other arguments that are matchers like any(), anyOrNull() etc. you can use matchers and literals at the same time.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.