Vraptor unit test Mockito (CDI)

1

Can anyone give me a glimpse of how to do unit tests using Mockito next to the full CDI of the Vraptor application?

I use a lot of CDI to control my objects like automated management of my dao next to the manager with the @Inject.

More using the unit tests, the same is not instantiating these objects that should be injected automatically.

If I give an @InjectMocks in my Dao, beauty, plus the @inject within the Dao class that gets my EntityManager does not work, and is not injected.

I then tried to do @InjectMocks in the EntityManager and instantiate my Dao class in the hand passing it, but to no avail. Apparently the Mock inject does not have the power to do this in the EntityManager.

Can someone give me a light?

Thank you.

    
asked by anonymous 10.11.2016 / 13:17

1 answer

0

It does not work as you think, when you are running unit tests you are in a standalone context, everything should be done in the same way, ex: if you want to test your repositories (DAO's) you could create a suite of tests where you have an abstract class that all your tests should extend, it will be responsible for creating the factory, creating the entityManager, initiating a transaction, committing and then destroying the resources, this will run for each test, testing everything in an isolated way, only you see the detail, you want to test repositories (DAO's) and this is no longer a unit test to be integration test, eg:

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import org.junit.AfterClass;
import org.junit.BeforeClass;

/**
 * Classe abstrata utilizada para testes, responsável por abrir conexão com
 * HSQLDB e encerrar os recursos após uso.
 *
 * @author Dilnei Cunha
 */
public abstract class AbstractRepositoryTest {

    protected static EntityManagerFactory emFactory;
    protected static EntityManager em;

    /**
     * Abrindo conexão com o Database, criando a EntityManager e abrindo a
     * transação.
     */
    @BeforeClass
    public static void setUp0() {
        emFactory = Persistence.createEntityManagerFactory("seu-ejbPU-test");
        em = emFactory.createEntityManager();
        em.getTransaction().begin();
    }

    /**
     * Comita a transação, encerra a EntityManager e a factory.
     */
    @AfterClass
    public static void tearDown0() {
        em.getTransaction().commit();
        em.close();
        emFactory.close();
    }
}

If you are accustomed to testing development, you know that you should use a persistence.xml for the tests you are in

  

src \ test \ resources \ META-INF \ persistemce.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd" version="2.1">
    <persistence-unit name="seu-ejbPU-test" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

        <class>br.com.suaApp.model.entity.SuaEntidade</class>
        .... suas classes 
        <properties>
            <property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbc.JDBCDriver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:mem:meubanco-test" />
            <property name="javax.persistence.jdbc.user" value="sa" />
            <property name="javax.persistence.jdbc.password" value="" />
            <property name="javax.persistence.schema-generation.database.action" value="drop-and-create" />
            <property name="hibernate.show_sql" value="true" />
        </properties>
    </persistence-unit>
</persistence>

In my case for repository tests I usually use memory banks, so for each test I insert the records for the repository to be tested, also notice that in the action I use drop-and-create where each time I squeeze the tests I destroy everything and I create again, I do not know if it uses enterprise containers (JavaEE full application servers) but realize that the transactinal type is RESOURCE_LOCAL and not JTA if it is the case.

example of what a repository test would look like:

import org.junit.Before;
import org.junit.Test;

public class SeuObjetoRepositoryTest extends AbstractRepositoryTest {

    private SeuObjetoRepository repository;
    private SeuObjeto seuObjeto1;
    private SeuObjeto seuObjeto2;

        repository = new SeuObjectoRepository(em);

        seuObjeto1 = new SeuObjeto(1L, "Joao", "teste", "12345678987");
        seuObjeto1 = repository.salvar(seuObjeto1);
        em.refresh(seuObjeto1);

        seuObjeto2 = new SeuObjeto(2L, "Zeneida", "teste2", "12345678987");
        seuObjeto2 = repository.salvar(seuObjeto2);
        em.refresh(seuObjeto2);
       ....
    }

    @Test
    public void testBuscaListaSeusObjetos() {
        List<SeuObjeto> objetos = repository.buscarLista();
        assertThat(objetos, contains(seuObjeto2, seuObjeto1));
        assertThat(objetos, not(contains(seuObjeto2, seuObjeto1)));
    }

    @After
    public void tearDown() {
        repository.excluir(seuObjeto1);
        repository.excluir(seuObjeto2);
        ....destruir tudo no final da execução do teste.
    }
}

To test the services, you should use Mocks as you should already know, because as your repositories have already been tested they should not be tested again, if your service uses the repository it should be mockado, eg

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

/**
 * @author Dilnei Cunha
 */
public class SeuObjetoServiceBeanTest {

    private seuObjetoServiceLocal seuObjetoServiceBean;

    @Mock
    private SeuObjetoRepository seuObjetoRepository;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        seuObjetoServiceBean = new SeuObjetoServiceBean(seuObjetoRepository);
    }

    @Test
    public void testSuaLogicaDeNegociosDependedoOQueOServicoFaz() {

        when(seuObjetoDatabase).thenReturn(seuObjeto);
        ........
    }
        ......... demais testes
}

For other testing options, if you want your tests to look like the actual application running with everything integrated, then you should use a testing engine like Arquillian , I use it is very powerful, even at the time of testing I upload an embedded container like Wildfly and I can test all injections and dependencies, however the way to program it changes, at the beginning it may be a bit arduous set it up, but it would already be subject to another post, I hope I have helped you in something, a hug.

    
10.11.2016 / 14:36