Configuración y eliminación del complejo estado de la base de datos con Hibernate / Spring / JUnit

StackOverflow https://stackoverflow.com/questions/822846

  •  03-07-2019
  •  | 
  •  

Pregunta

Tengo una clase de prueba de unidad que requiere una configuración de base de datos bastante extensa antes de que se puedan ejecutar los métodos de prueba individuales. Esta configuración lleva mucho tiempo: por razones que, probablemente, no sean relevantes para la pregunta en cuestión, debo rellenar el DB programáticamente en lugar de hacerlo desde un volcado de SQL.

El problema que tengo es con el desmontaje. ¿Cómo puedo revertir fácilmente todos los cambios realizados en la fase de configuración de la base de datos?

Actualmente estoy usando el soporte de Pruebas Transaccionales Hibernate + Spring, por lo que mis métodos de prueba individuales están envueltos en transacciones.

Una solución sería realizar la configuración de db dentro de cada método de prueba, de manera que la configuración de db se deshaga automáticamente. Sin embargo, los métodos de prueba tardarían una eternidad en ejecutarse, ya que cada método tendría que volver a preparar la base de datos.

¿Alguna otra idea? Básicamente, estoy buscando una manera de ejecutar mi configuración de db, ejecutar mis pruebas individuales (cada una envuelta en una transacción que se retrotrae después de la ejecución), y luego deshacer la configuración inicial de db. ¿Alguna idea sobre cómo hacer que esto funcione en modo Hibernate / Spring / Junit? ¿Hay un Hibernar " soltar todas las tablas " comando equivalente?

¿Fue útil?

Solución

¿Está atrapado en un proveedor de base de datos específico? Si no, puede usar una base de datos en memoria, como HSQLDB . Cuando haya terminado con las pruebas, acaba de tirar el estado. Esto solo es apropiado si las tablas pueden estar vacías al comienzo del conjunto de pruebas (antes de su configuración programática).

Aún necesita crear tablas, pero si todo está correctamente asignado mediante Hibernate, puede usar hbm2ddl para generar sus tablas. Todo lo que tiene que hacer es agregar lo siguiente a su prueba definición de fábrica de sesión:

<session-factory>
    ...
    <property name="hibernate.hbm2ddl.auto">create</property>
    ...
</session-factory>

Si esta solución parece aplicable, puedo desarrollarla.

Otros consejos

Es posible que desee consultar la anotación @AfterClass, para Junit 4. Esta anotación se ejecutará cuando se realicen las pruebas.

http://cwiki.apache.org/DIRxDEV/junit4-primer.html

DNUnit debería ayudarte en este sentido. Puede crear conjuntos de datos separados para cada caso de prueba individual si lo desea.

DBUnit ayudará mucho con esto. Teóricamente, podrías desactivar los autocomodos en JDBC, pero se volverá peludo. La solución más obvia es usar DBUnit para establecer sus datos en un estado conocido antes de ejecutar las pruebas. Si, por algún motivo, necesita recuperar sus datos después de ejecutar las pruebas, puede consultar @AfterClass en una suite que ejecuta todas sus pruebas, pero generalmente se considera una mejor práctica para configurar las pruebas y luego ejecutarlas, por lo que que si la prueba falla, no es solo porque no tenía un entorno prestine debido a una falla en limpiar una prueba diferente. Usted se asegura de que cada prueba configure su entorno directamente.

Una solución que quizás desee considerar es utilizar un " manual " Rollback o transacción de compensación en db tear down. Supongo que (y si no lo es, debería ser un complemento trivial para sus entidades de Hibernación) todas sus entidades tienen un atributo de creación de fecha y hora que indica cuándo se insertaron en la tabla. Su método de configuración de db debe registrar el tiempo antes de todo lo demás. Luego, tiene un procedimiento bastante simple para que db tear down elimine todas las entidades que se crearon después del tiempo restaurado en la configuración de db.

Por supuesto, esto no funcionará con las actualizaciones en la configuración de la base de datos ... Pero si tiene un número limitado de actualizaciones, considere guardar una imagen prístina para este tipo de datos y restaurarla durante la eliminación de la base de datos.

Si está trabajando con una base de datos relativamente pequeña, y con un DBMS que puede hacer copias de seguridad / exportaciones de la misma relativamente rápida (como MS SQL Server), puede considerar crear una copia de seguridad de la base de datos antes de las pruebas, y luego restaurarla cuando todas las pruebas están completas Esto le permite configurar una base de datos de desarrollo / prueba y usarla como estado de inicio para todas sus pruebas.

Lo hice con JDBC nativo, ejecutando T-SQL de '' base de datos de respaldo '' y '' de base de datos de restauración '', y funcionó razonablemente bien.

Sin embargo, este enfoque depende de tener el servidor DBMS en su máquina local (para una velocidad razonable), de tener suficientes privilegios (lo que no debería ser un problema) y el tamaño total de la base de datos que no exceda algunas tensiones. MB - al menos en mi experiencia.

¿Hay alguna razón por la que deba tener una conexión a la base de datos para ejecutar las pruebas de unidad? Parece que podría ser más fácil refactorizar tu clase para que puedas simular la interacción con la base de datos. Puede simular clases (con algunas excepciones), así como interfaces con EasyMock (www.easymock.org).

Si su clase se basa en un estado complejo preexistente en una base de datos conectada, probablemente sería más fácil escribir más rápido ejecutando pruebas utilizando simulacros. No sabemos cuál es el tamaño de su proyecto o con qué frecuencia se ejecutan sus pruebas, pero el tiempo de ejecución puede ser algo en que pensar, especialmente en un proyecto grande.

Hibernate tiene una pequeña característica que está muy poco documentada y es desconocida. Puede ejecutar un script SQL durante la creación de SessionFactory justo después de la generación del esquema de la base de datos para importar datos en una base de datos nueva. Solo necesita agregar un archivo llamado import.sql en la raíz de su ruta de clase y establecer crear o crear y soltar como su propiedad hibernate.hbm2ddl.auto.

http://in.relation.to/Bloggers/RotterdamJBugAndHibernatesImportsql

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top