It is that it does not work as you think, when you are running the unit tests you are in a standalone context, everything should be done in a very manual way, eg: if you want to test your repositories (DAO’s) you could create a test suite where you have an abstract class that all your tests must extend, it will be responsible for creating the factory, create the entityManager, start a transaction, commit and then destroy the resources, this will run for each of the tests, testing everything in isolation, just so you know the detail, you want to test repositories (DAO’s) and this is no longer a unit test to be integration test, ex:
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 used to developing tests, you know that you should use persistence.xml for the tests you get 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 testing I usually use memory banks, so for each test I insert the records referring to the repository that will be tested, also note that in the action I use drop-and-create where every time I run the tests I destroy everything and create again, I don’t know if it uses containers Enterprise(full Javaee application servers) but notice that the transactinal type is RESOURCE_LOCAL and not JTA if applicable.
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 may already know, as your repositories have already been tested they should not be tested again, if your service uses the repository it should be mocked, e.g.:
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
}
The other options for testing, if you want your tests to look like the actual application running with everything integrated, then you should use a test engine like the Arquillian, I use it is very powerful, even at the time of the tests I climb an Embedded container like Wildfly and I can test all injections and dependencies, but the way to program this changes, at first it may be a bit arduous to configure it, but it would already be subject to another post, I hope I helped you with something, hugging.
It was what I really had in mind, having to build everything in hand like Entityfactory and etc... so I didn’t think much so that directly what resources would be. But your post has really helped me understand how it works.
– Kelvin Stang Oenning