adam bien's blog

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