Mockito's JavaDocs on verify methods link to this interesting article about asking and telling. I'm a bit lost there specially with the "stubbed interactions are verified implicitly".
Let's take an example:
Imagine a have this class
class FooDao {
private EntityManager entityManager;
public FooDao(EntityManager entityManager) {
this.entityManager = entityManager;
}
public List<Foo> findFooByName(String name, String otherParam) {
String hql = "SELECT f FROM Foo f WHERE 1 = 1 ";
if(name != null) {
hql += " AND f.name = :name";
}
if(otherParam != null) {
hql += " AND f.other = :otherParam";
}
TypedQuery<Foo> query = this.entityManager.createQuery(hql, Foo.class);
if(name != null) {
query.setParameter("name", name);
}
if(otherParam != null) {
query.setParameter("otherParam", otherParam);
}
return query.getResultList();
}
}
Now, let's see what can I check about this method:
- That the HQL query is constructed properly for the parameters given.
- That the parameters are correctly bound to the query object.
- That the result is what I expect.
First of all I will mock the EntityManager object because I don't want to access a real database.
@InjectMocks
private FooDao dao;
@Mock
private EntityManager entityManager;
Now, I could just add something like this:
@Mock
private TypedQuery<Foo> mockQuery;
@Test
public void testFindFooByName() {
List<Foo> stubData = stubData(); // Method definition omitted for brevity
// Return the custom mockedQuery with the entityManager
Mockito.when(mockQuery.getResultList()).thenReturn(stubData);
Mockito.when(entityManager.createQuery(Mockito.anyString(),
Mockito.eq(Foo.class)))
.thenReturn(mockQuery);
List<Foo> actual = dao.findFooByName("foobar", null);
// Now what should I check?
}
So, now the question is what to check. I could just add an assertEquals(stubData, actual) and the test would succeed.
I could also add:
Mockito.verify(entityManager).createQuery(expectedSql, Foo.class);
Mockito.verify(mockQuery).setParameter("name", "foobar");
The first verification will ensure that the HQL query has been constructed properly and the second one will ensure that the parameter was correctly bound to the query. Are these verifications necessary at all or just asserting the result is enough?