Base en memoria y pruebas

Y ahora lo más interesante. Al probar el código de Hibernate, muy a menudo desea trabajar no con una base real, sino con algún tipo de código auxiliar que implementa una funcionalidad mínima.

¿Te imaginas un código auxiliar que implementa la mayor parte del estándar de SQL Server? Yo no. Sin embargo, las bases de datos en memoria son excelentes como tales. Funciona más o menos así:

  • En el método @BeforeAll, inicializamos la conexión de la base de datos en memoria.
  • En el método @BeforeEach, obtenemos la sesión y abrimos una transacción.
  • En el método @Test, trabajamos con la sesión y transacción actual.
  • En el método @AfterEach, confirmamos la transacción.
  • Y finalmente, en el método AfterAll, cerramos la conexión a la base de datos.

Así es como se ve la preparación para la prueba:

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

Y así es como se ve la prueba en sí con el trabajo de 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());
  }
}

datos de prueba

También puede llenar su base de datos de prueba con datos de prueba.

Por lo general, se crean dos archivos sql para esto:

  • schema.sql contiene un script que crea tablas en la base de datos
  • test-data.sql contiene un script que llena tablas con datos de prueba

La creación de tablas y los datos de prueba generalmente se separan en archivos diferentes, ya que casi siempre aparecen sus propios grupos de datos de prueba para diferentes grupos de prueba.

La ejecución de estos archivos se ve así:

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

Y su método de configuración cambiará un poco:

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