Base en mémoire et tests
Et maintenant le plus intéressant. Lorsque vous testez du code Hibernate, vous souhaitez très souvent travailler non pas avec une base réelle, mais avec une sorte de stub qui implémente des fonctionnalités minimales.
Pouvez-vous imaginer un stub qui implémente la plupart de la norme SQL Server ? Pas moi. Cependant, les bases de données en mémoire sont excellentes en tant que telles. Cela fonctionne à peu près comme ceci :
- Dans la méthode @BeforeAll, nous initialisons la connexion à la base de données en mémoire.
- Dans la méthode @BeforeEach, nous obtenons la session et ouvrons une transaction.
- Dans la méthode @Test, nous travaillons avec la session et la transaction en cours.
- Dans la méthode @AfterEach, nous validons la transaction.
- Et enfin, dans la méthode AfterAll, nous fermons la connexion à la base de données.
Voici à quoi ressemble la préparation du test :
@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();
}
Et voici à quoi ressemble le test lui-même avec le travail d'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());
}
}
données de test
Vous pouvez également remplir votre base de données de test avec des données de test.
Généralement, deux fichiers sql sont créés pour cela :
- schema.sql contient un script qui crée des tables dans la base de données
- test-data.sql contient un script qui remplit les tables avec des données de test
La création de table et les données de test sont généralement séparées dans différents fichiers, car leurs propres groupes de données de test pour différents groupes de test apparaissent presque toujours.
L'exécution de ces fichiers ressemble à ceci :
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()
}
Et votre méthode de configuration changera un peu :
@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);
}
}