Mocking JPA EntityManager with Query 📎
EntityManager
is an interface and can be easily mocked out with https://code.google.com/p/mockito/.
At the same time the EntityManager
is also a factory, which creates Query
instance, which in turn creates results. Mocking a query involves therefore a three step (=three lines process):
public class RegistrationsTest {
Registrations cut;
@Before
public void init() {
this.cut = new Registrations();
this.cut.priceCalculator = mock(VatCalculator.class);
this.cut.em = mock(EntityManager.class);
//...
}
void mockQuery(String name, List<Registration> results) {
Query mockedQuery = mock(Query.class);
when(mockedQuery.getResultList()).thenReturn(results);
when(this.cut.em.createNamedQuery(name)).thenReturn(mockedQuery);
}
After this step you can easily return whatever results you like:
@Test
public void convertEmptyListToJson() {
mockQuery(Registration.findAll, Collections.EMPTY_LIST);
final JsonArray result = this.cut.allAsJson();
assertNotNull(result);
assertTrue(result.isEmpty());
}
If you would like to ignore the parameters, or react to specific query parameters, the method Query::setParameter needs to be mocked as well:
when(mockedQuery.setParameter(Matchers.anyString(), Matchers.anyObject())).thenReturn(mockedQuery);
See the entire unit test: RegistrationsTest.java. The whole example is available as maven archetype.
Usually complex queries are going to be encapsulated in dedicated controls, so it is easier to mock out the whole control instead.
Interested in Java EE Code Quality and Testing? See you at http://workshops.adam-bien.com/about-testing.htm or regular http://airhacks.com