База в пам'яті та тестування
А тепер найцікавіше. При тестуванні коду Hibernate дуже часто хочеться працювати не з реальною базою, а з якоюсь заглушкою, що реалізує мінімальну функціональність.
А ти уявляєш заглушку, яка реалізує більшу частину стандарту SQL-сервера? Я – ні. Однак як така відмінно підходять бази даних у пам'яті. Працює це приблизно за такою схемою:
- У методі @BeforeAll ми ініціалізуємо з'єднання з базою даних у пам'яті.
- У методі @BeforeEach ми отримуємо сесію та відкриваємо транзакцію.
- У методі @Test ми працюємо з поточною сесією та транзакцією.
- У методі @AfterEach ми дотримуємося транзакції.
- І нарешті у методі AfterAll ми закриваємо з'єднання з базою.
Ось як виглядає підготовка до роботи тесту:
@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();
}
А ось так виглядає сам тест із роботою 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());
}
}
Тестові дані
Також ти можеш заповнити тестову базу тестовими даними.
Зазвичай для цього роблять два sql-файли:
- schema.sql містить скрипт, який створює таблиці в базі
- test-data.sql містить скрипт, який заповнює таблиці тестовими даними
Створення таблиці і тестові дані зазвичай розносять по різних файлух, оскільки завжди з'являються свої групи тестових даних для різних груп тестів.
Виконання цих файлів виглядає так:
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()
}
І твій метод setup трохи зміниться:
@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);
}
}
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ