Es importante poder realizar algunas pruebas de integración sin necesariamente implementarlas en un servidor de aplicaciones o conectarse a otra infraestructura corporativa. Esto le permitirá probar cosas como:

  • Conexión correcta de contextos de contenedores Spring IoC.

  • Acceda a los datos mediante la herramienta JDBC u ORM. Esto puede incluir, entre otros, la exactitud de las declaraciones SQL, consultas de Hibernate, asignaciones de entidades JPA, etc.

Spring Framework proporciona soporte de primera clase para pruebas de integración en el módulo spring-test. El nombre del archivo JAR real puede incluir la versión de lanzamiento y también puede estar en el formato largo org.springframework.test, dependiendo de dónde lo obtenga (consulte la sección sobre administración de dependencias para aclaración) . Esta biblioteca incluye el paquete org.springframework.test, que contiene clases útiles para pruebas de integración utilizando el contenedor Spring. Esta prueba es independiente del servidor de aplicaciones u otro entorno de implementación. Estas pruebas se ejecutan más lentamente que las pruebas unitarias, pero son mucho más rápidas que las pruebas Selenium equivalentes o las pruebas remotas que dependen de la implementación en el servidor de aplicaciones.

El soporte para pruebas unitarias y de integración se proporciona en forma de un marco Spring TestContext orientado a anotaciones. El marco TestContext es independiente de la infraestructura de prueba real en uso, lo que le permite instrumentar pruebas en varios entornos, incluidos JUnit, TestNG y otros.

Objetivos de las pruebas de integración

El soporte para las pruebas de integración en Spring tiene los siguientes objetivos principales:

  • Administre el almacenamiento en caché del contenedor Spring IoC entre pruebas.

  • Garantizar la inyección de dependencia para instancias de banco de pruebas (entorno).

  • Proporcionar cumplimiento con las pruebas de integración.

  • Proporciona clases principales específicas de Spring que ayudan a los desarrolladores a escribir pruebas de integración.

Las siguientes secciones describen cada objetivo y proporcionan enlaces a explicaciones detalladas de implementación y configuración.

Gestión de contexto y almacenamiento en caché

El marco

Spring TestContext proporciona carga secuencial de instancias ApplicationContext y WebApplicationContext desde Spring, así como almacenamiento en caché de estos contextos. La compatibilidad con el almacenamiento en caché de contextos cargados es importante porque el tiempo de inicio inicial puede ser un problema, no debido a la latencia en Spring en sí, sino porque los objetos instanciados por el contenedor Spring tardan en crearse. Por ejemplo, en un proyecto con entre 50 y 100 archivos de visualización, Hibernate puede tardar entre 10 y 20 segundos en cargar los archivos de visualización, y esta sobrecarga antes de ejecutar cada prueba en cada banco de pruebas da como resultado un proceso de prueba general más lento, lo que reduce la productividad del desarrollador. /p>

Las clases de prueba normalmente declaran una matriz de ubicaciones de recursos para metadatos de configuración XML o Groovy (a menudo en el classpath) o una matriz de clases de componentes que se utilizan para configurar la aplicación. Estas ubicaciones o clases son iguales o similares a las especificadas en web.xml u otros archivos de configuración para la implementación de producción.

De forma predeterminada, después de la carga, el ApplicationContext configurado se reutiliza para cada prueba. De esta manera, los recursos de configuración se gastan solo una vez para cada conjunto de pruebas y las ejecuciones de pruebas posteriores son mucho más rápidas. En este contexto, el término "conjunto de pruebas" significa todas las pruebas que se ejecutan en una única JVM; por ejemplo, todas las pruebas que se ejecutan desde una compilación Ant, Maven o Gradle para un proyecto o módulo determinado. En el improbable caso de que una prueba corrompa el contexto de la aplicación y requiera una recarga (por ejemplo, cuando cambia la definición de un bean o el estado de un objeto de la aplicación), el marco TestContext se puede configurar para recargar la configuración y restaurar el contexto de la aplicación antes de ejecutar la prueba. próxima prueba.

Inyección de dependencia para bancos de pruebas

Cuando el marco TestContext carga el contexto de la aplicación, opcionalmente puede configurar instancias de sus clases de prueba mediante la inyección de dependencia. Esto le permite proporcionar un mecanismo conveniente para configurar bancos de pruebas utilizando beans preconfigurados desde el contexto de su aplicación. El gran beneficio aquí es la capacidad de reutilizar contextos de aplicaciones en diferentes escenarios de prueba (por ejemplo, para configurar gráficos de objetos administrados por Spring, proxies transaccionales, instancias DataSource, etc.), eliminando la necesidad de duplicar complejos Configuraciones de banco de pruebas para casos de prueba individuales.

Como ejemplo, considere un escenario en el que tenemos una clase (HibernateTitleRepository) que implementa la lógica de acceso a datos para una entidad de dominio Title. Queremos escribir pruebas de integración que prueben las siguientes áreas:

  • Configuración de Spring: Principalmente, ¿está todo lo necesario relacionado con la configuración del bean HibernateTitleRepository presente y correctamente?

  • Configuración del archivo de mapeo de Hibernación: ¿Está todo mapeado correctamente y tiene configuradas las configuraciones de carga diferida correctas?

  • Lógica del repositorio HibernateTitleRepository: ¿La instancia configurada de esta clase realiza la funcionalidad esperada?

Gestión de transacciones

Un problema común con las pruebas que acceden a una base de datos real es su impacto en el estado del almacén de persistencia. Incluso si utiliza la base de datos para el desarrollo, los cambios de estado pueden afectar las pruebas futuras. Además, muchas operaciones, como insertar o modificar datos persistentes, no se pueden realizar (ni verificar) fuera de una transacción.

El marco TestContext resuelve este problema. De forma predeterminada, el marco crea y revierte una transacción para cada prueba. Es posible escribir código que pueda asumir la existencia de una transacción. Si llama a objetos proxy de forma transaccional en sus pruebas, se comportan correctamente de acuerdo con la semántica de transacción configurada. Además, si un método de prueba elimina el contenido de las tablas seleccionadas mientras se ejecuta una transacción administrada por prueba, la transacción se revierte de forma predeterminada y la base de datos regresa al estado anterior a la ejecución de la prueba. El soporte de transacciones se proporciona a una prueba utilizando el bean PlatformTransactionManager definido en el contexto de la aplicación de prueba.

Si necesita que se confirme la transacción (no estándar, pero a veces útil si desea que una prueba particular complete o modifique la base de datos), puede indicarle al marco TestContext que haga que la transacción se confirme en lugar de retroceder. usando la anotación @Commit.

Ver gestionar transacciones utilizando el marco TestContext (ver enlace al final de la conferencia).

Clases de ayuda para pruebas de integración

El

Spring TestContext Framework proporciona varias clases auxiliares abstract que facilitan la escritura de pruebas de integración. Estas clases de prueba principales proporcionan interceptores bien definidos que se conectan al marco de prueba, así como variables y métodos de instancia auxiliares que le permiten acceder a:

  • ApplicationContext: para realizar búsquedas explícitas de beans o probar el estado del contexto en su conjunto.

  • JdbcTemplate: para ejecutar sentencias SQL para consultas de bases de datos. Puede utilizar dichas consultas para validar el estado de la base de datos antes y después de ejecutar el código de la aplicación asociado con la base de datos, y Spring se asegurará de que dichas consultas se ejecuten dentro de la misma transacción que el código de la aplicación. Cuando se utiliza junto con una herramienta ORM, se deben evitar los falsos positivos (ver enlace al final de la conferencia).

Como alternativa, es posible que necesites crear tu propia superclase personalizada para toda la aplicación con variables de instancia y métodos específicos de tu proyecto.

Ver todo sobre el marco TestContext y su interacción con: “Gestión de contexto/almacenamiento en caché”, clases auxiliares para el marco, y también inyectar dependencias en bancos de pruebas y gestionar transacciones utilizando.