No artigo de hoje vamos ver como executar nossos unit tests usando o DBunit com HSQLDB em memória, tendo o Hibernate como framework de persistência e usando o maven. Por que isso tudo? Eu passei por uns problemas chatos de configuração que normalmente não temos quando fazemos testes de cada um desses recursos separados, mas, quando tive que colocar tudo na mesma panela, surgiram uns problemas mais chatos para nós, desenvolvedores. Estou falando daquelas exceções de não achar o arquivo; exceções genéricas dos frameworks, que nos faz ficar horas e horas googlando, etc.
O que vou considerar?
Que você já conhece Hibernate e conhece o DBunit, porém agora pretende rodar seus testes em um projeto do tipo maven e você tem dois arquivos hibernate.cfg.xml: um para os testes e outro para a aplicação em si.
O problema
Tudo começou quando, ao executar meus testes, simplesmente recebi aquela velha mensagem: cannot open JDBC Connection. Eu intrigado, afinal, o hibernate.cfg.xml estava lá. Então, comecei a investigar… Um ponto eu já sabia: o maven procura o hibernate.cfg.xml em src/main/resources. E para os testes? Ele procura em src/test/resources. Até parece lógico, mas errei aqui e não coloquei meu arquivo de hibernate.cfg.xml de teste nesse local. Porém, veio outro problema: eu tinha renomeado meu arquivo hibernate.cfg.xml para hibernateTest.cfg.xml. Por que? Simplesmente queria ter essa diferença. E deixava assim a configuração nos meus testes:
protected IDatabaseConnection getConnection() throws Exception { conn = new DatabaseConnection(new Configuration().configure("hibernateTest.cfg.xml") .buildSettings().getConnectionProvider().getConnection()); return conn; }
Simplesmente recebia:
O que fiz? Mudei o arquivo para hibernate.cfg.xml e rodei a aplicação e o resultado:
Isso me custou umas 3hr do meu dia. Infelizmente não fui pesquisar porque com o nome diferente do Hibernate o maven não encontrava o arquivo, somente com o nome default.
O arquivo do DBunitTest é o mesmo que vimos anteriormente, a única diferença é que temos um projeto do tipo “simple maven project”.
Hibernate.cfg.xml para o HSQLDB
<session-factory> <property name="hibernate.connection.driver_class">org.hsqldb.jdbcDriver</property> <property name="hibernate.connection.url">jdbc:hsqldb:mem:db</property> <property name="hibernate.connection.username">sa</property> <property name="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property> <property name="hibernate.show_sql">true</property> <property name="hibernate.hbm2ddl.auto">create-drop</property> <mapping class="com.camilolopes.qa.model.dao.bean.Account"/> </session-factory>
Configuração do pom.xml: adicione as dependencias abaixo:
<dependency> <groupId>hsqldb</groupId> <artifactId>hsqldb</artifactId> <version>1.8.0.10</version> </dependency> <dependency> <groupId>javassist</groupId> <artifactId>javassist</artifactId> <version>3.12.1.GA</version> <type>jar</type> <scope>compile</scope> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>3.6.10.Final</version> <type>jar</type> <scope>compile</scope> </dependency> <dependency> <groupId>org.dbunit</groupId> <artifactId>dbunit</artifactId> <version>2.4.8</version> <type>jar</type> <scope>compile</scope> </dependency>
Crie um bean e um teste para persistir o objeto:
Bean
@Entity @Table(name="account") public class Account { @Id @GeneratedValue @Column(name="ID") private Long id; @Column(length=20,name="TYPE") private String type;
Test
A classe de test deverá estar assim, e omitir o que não mudou do outro arquivo, como a conexão e o load do .xml.
public DBUnitTest() { try { session = getSessionFactory().openSession(); getDataSet(); } catch (Exception e) { e.getMessage(); } } public static SessionFactory getSessionFactory() { sessionFactory = new Configuration().configure().buildSessionFactory(); return sessionFactory; } @Test public void testSave(){ session.beginTransaction(); Account account = new Account(); account.setType("USER"); session.save(account); }
Enfim, é isso ai. Caso precise rodar seus unit tests com maven + hibernate + hsqldb, sem ter dor de cabeça com arquivo de configuração, essa foi a solução que encontrei.
Abracos!