База в паметта и тестване

И сега най-интересното. Когато тествате codeа на Hibernate, много често искате да работите не с истинска база, а с няHowъв вид мъниче, което изпълнява минимална функционалност.

Можете ли да си представите мъниче, което внедрява по-голямата част от стандарта на SQL Server? Аз не. Базите данни в паметта обаче са отлични като такива. Работи приблизително така:

  • В метода @BeforeAll инициализираме връзката с база данни в паметта.
  • В метода @BeforeEach получаваме сесията и отваряме транзакция.
  • В метода @Test работим с текущата сесия и транзакция.
  • В метода @AfterEach извършваме транзакцията.
  • И накрая, в метода AfterAll затваряме връзката с базата данни.

Ето How изглежда подготовката за теста:

@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();
  }

А ето How изглежда самият тест с работата на 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 file:

  • schema.sql съдържа скрипт, който създава таблици в базата данни
  • test-data.sql съдържа скрипт, който попълва таблици с тестови данни

Създаването на table и данните за тестване обикновено са разделени в различни файлове, тъй като почти винаги се появяват собствени групи от тестови данни за различни тестови групи.

Изпълнението на тези файлове изглежда така:

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()
}

И вашият метод на настройка ще се промени малко:

@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);
  }
}