Base na memória e teste
E agora o mais interessante. Ao testar o código do Hibernate, muitas vezes você deseja trabalhar não com uma base real, mas com algum tipo de stub que implementa funcionalidade mínima.
Você consegue imaginar um stub que implemente a maior parte do padrão SQL Server? Eu não. No entanto, os bancos de dados na memória são excelentes como tal. Funciona mais ou menos assim:
- No método @BeforeAll, inicializamos a conexão do banco de dados na memória.
- No método @BeforeEach, obtemos a sessão e abrimos uma transação.
- No método @Test, trabalhamos com a sessão e a transação atuais.
- No método @AfterEach, confirmamos a transação.
- E por fim, no método AfterAll, fechamos a conexão com o banco de dados.
Veja como é a preparação para o teste:
@Test
public class HelloTest {
private static SessionFactory sessionFactory = null;
private Session session = null;
@BeforeAll
static void setup(){
try {
StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder()
.configure("hibernate-test.cfg.xml").build();
Metadata metadata = new MetadataSources(standardRegistry)
.addAnnotatedClass(Employee.class)
.getMetadataBuilder()
.build();
sessionFactory = metadata.getSessionFactoryBuilder().build();
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
@BeforeEach
void setupThis(){
session = sessionFactory.openSession();
session.beginTransaction();
}
@AfterEach
void tearThis(){
session.getTransaction().commit();
}
@AfterAll
static void tear(){
sessionFactory.close();
}
E é assim que o teste em si se parece com o trabalho do Hibernate:
@Test
public class HelloTest {
@Test
void createSessionFactoryWithXML() {
Employee emp = new Employee();
emp.setEmail("demo-user@mail.com");
emp.setFirstName("demo");
emp.setLastName("user");
Assertions.assertNull(emp.getEmployeeId());
session.persist(emp);
Assertions.assertNotNull(emp.getEmployeeId());
}
}
dados de teste
Você também pode preencher seu banco de dados de teste com dados de teste.
Geralmente dois arquivos sql são feitos para isso:
- schema.sql contém um script que cria tabelas no banco de dados
- test-data.sql contém um script que preenche tabelas com dados de teste
A criação da tabela e os dados de teste geralmente são separados em arquivos diferentes, pois quase sempre aparecem seus próprios grupos de dados de teste para diferentes grupos de teste.
A execução desses arquivos fica assim:
void runSqlScriptFile(String filePath){
String sqlScript = new String( Files.readAllBytes(Paths.get(filePath)) );
Session session = sessionFactory.openSession();
Query query = session.createNativeQuery("BEGIN " + sqlScript + " END;");
query.executeUpdate()
}
E seu método de configuração mudará um pouco:
@BeforeAll
static void setup(){
try {
StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder()
.configure("hibernate-test.cfg.xml").build();
Metadata metadata = new MetadataSources(standardRegistry)
.addAnnotatedClass(Employee.class)
.getMetadataBuilder()
.build();
sessionFactory = metadata.getSessionFactoryBuilder().build();
runSqlScriptFile(“scema.sql”);
runSqlScriptFile(“test-data.sql”);
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}