Base i hukommelse og test
Og nu det mest interessante. Når du tester Hibernate-kode, vil du meget ofte ikke arbejde med en rigtig base, men med en slags stub, der implementerer minimal funktionalitet.
Kan du forestille dig en stub, der implementerer det meste af SQL Server-standarden? Mig ikke. In-memory-databaser er dog fremragende som sådan. Det fungerer nogenlunde sådan her:
- I @BeforeAll-metoden initialiserer vi databaseforbindelsen i hukommelsen.
- I @BeforeEach-metoden får vi sessionen og åbner en transaktion.
- I @Test-metoden arbejder vi med den aktuelle session og transaktion.
- I @AfterEach-metoden forpligter vi transaktionen.
- Og til sidst, i AfterAll-metoden, lukker vi forbindelsen til databasen.
Sådan ser forberedelsen til testen ud:
@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();
}
Og sådan ser selve testen ud med arbejdet med 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());
}
}
testdata
Du kan også udfylde din testdatabase med testdata.
Normalt laves to sql-filer til dette:
- schema.sql indeholder et script, der opretter tabeller i databasen
- test-data.sql indeholder et script, der udfylder tabeller med testdata
Tabeloprettelse og testdata er normalt opdelt i forskellige filer, da deres egne grupper af testdata for forskellige testgrupper næsten altid vises.
Udførelse af disse filer ser sådan ud:
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()
}
Og din opsætningsmetode vil ændre sig en smule:
@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);
}
}
GO TO FULL VERSION