A partir de Spring Framework 5.3.3, el marco TestContext brinda soporte para registrar eventos de aplicaciones
publicados en ApplicationContext
para que las pruebas se puedan afirmar contra esos eventos. Todos los
eventos publicados durante la ejecución de una única prueba están disponibles a través de la API ApplicationEvents
,
que permite que los eventos se procesen como java.util.Stream
.
Para utilizar ApplicationEvents
en sus pruebas, haga lo siguiente.
-
Asegúrese de que su clase de prueba esté anotada o metaanotada con
@RecordApplicationEvents
. -
Asegúrese de que
ApplicationEventsTestExecutionListener
esté registrado. Tenga en cuenta queApplicationEventsTestExecutionListener
está registrado de forma predeterminada y solo necesita registrarlo manualmente si tiene una configuración especial a través de la anotación@TestExecutionListener
que no incluye oyentes de forma predeterminada. -
Anote un campo de tipo
ApplicationEvents
con la anotación@Autowired
y utilice esta instancia deApplicationEvents
en sus métodos de prueba y métodos de ciclo de vida (p. ej. métodos, marcados con las anotaciones@BeforeEach
y@AfterEach
en JUnit Jupiter).-
Al utilizar SpringExtension para JUnit Jupiter, puede declarar un parámetro de método de tipo
ApplicationEvents
en un método de prueba o de ciclo de vida como alternativa a un campo anotado@Autowired
en la clase de prueba.
-
La siguiente clase de prueba usa SpringExtension
para JUnit Jupiter y AssertJ para tipos de aserción de eventos de
aplicación publicados cuando se llama a un método en un bean administrado Spring:
@SpringJUnitConfig(/* ... */)
@RecordApplicationEvents
clase PruebasServicioPedido {
@autocableado
Servicio de pedidoServicio de pedido;
@autocableado
Eventos de eventos de aplicación;
@Prueba
anular enviarOrder() {
// Llama a un método en OrderService que publica un evento
orderService.submitOrder(nuevo pedido(/* ... */));
// Comprobar que el evento OrderSubmitted ha sido publicado
long numEvents = events.stream(OrderSubmitted.class).count();
afirmarQue(numEvents).isEqualTo(1);
}
}
- Anote la clase de prueba con
@RecordApplicationEvents
. - Inyecta una instancia de
ApplicationEvents
para la prueba actual. - Utilice la API
ApplicationEvents
para contar cuántos eventosOrderSubmitted
se han publicado.
@SpringJUnitConfig(/* ... */)
@RecordApplicationEvents
clase PruebasServicioPedido {
@autocableado
lateinit var orderService: OrderService
@autocableado
eventos lateinit var: ApplicationEvents
@Prueba
divertido enviarOrden() {
// Llama a un método en OrderService que publica el evento
orderService.submitOrder(Orden(/* ... */))
// Comprobar que el evento OrderSubmitted ha sido publicado
val numEvents = eventos.stream(OrderSubmitted::class).count()
afirmar que(numEvents).isEqualTo(1)
}
}
- Anote la clase de prueba con
@RecordApplicationEvents
. - Inyecta una instancia de
ApplicationEvents
para la prueba actual. - Utilice la API
ApplicationEvents
para contar cuántos eventosOrderSubmitted
se han publicado.
Ver javadoc por ApplicationEvents
para obtener más información sobre la API ApplicationEvents
.
Eventos de ejecución de prueba
El detector EventPublishingTestExecutionListener
, introducido en Spring Framework 5.2, ofrece un enfoque
alternativo para implementar un TestExecutionListener
personalizado. Los componentes de la prueba
ApplicationContext
pueden escuchar los siguientes eventos publicados por EventPublishingTestExecutionListener
,
cada uno de los cuales corresponde a un método en la API TestExecutionListener
.
-
BeforeTestClassEvent
-
PrepareTestInstanceEvent
-
BeforeTestMethodEvent
-
BeforeTestExecutionEvent
-
AfterTestExecutionEvent
-
AfterTestMethodEvent
-
AfterTestClassEvent
Estos eventos se pueden consumir por diversos motivos, como restablecer beans simulados o realizar un seguimiento de
la ejecución de pruebas. Una ventaja de consumir eventos de ejecución de pruebas en lugar de implementar un TestExecutionListener
especial es que los eventos de ejecución de pruebas pueden ser consumidos por cualquier Spring Bean registrado en el
ApplicationContext
de prueba, y dichos beans pueden directamente inyección de dependencia de beneficios
y otras funciones ApplicationContext
. Por el contrario, TestExecutionListener
no es un
bean en ApplicationContext
.
El oyente EventPublishingTestExecutionListener
está registrado de forma predeterminada; sin embargo,
solo publica eventos si el ApplicationContext
ya está cargado. Esto evita que ApplicationContext
se cargue innecesariamente o demasiado pronto.
Por lo tanto, el evento BeforeTestClassEvent
solo se publicará después de que otro TestExecutionListener
haya cargado el ApplicationContext
. Por ejemplo, con un conjunto de implementaciones TestExecutionListener
registradas de forma predeterminada, el evento BeforeTestClassEvent
no se publicará para la primera
clase de prueba que utilice un de prueba particular ApplicationContext
, pero el evento The BeforeTestClassEvent
se
se publicará para cualquier clase de prueba posterior en el mismo conjunto de pruebas que utilice el mismo
ApplicationContext
de prueba, ya que el contexto ya se cargará cuando se ejecuten las siguientes
clases de prueba (a menos que el contexto se haya eliminado de ContextCache
mediante la anotación
@DirtiesContext
o la política de desalojo cuando el tamaño máximo se alcanza).
Si desea que siempre se publique un evento BeforeTestClassEvent
para cada clase de prueba, debe
registrar un TestExecutionListener
que cargue el ApplicationContext
. en la devolución
de llamada >beforeTestClass
, y este TestExecutionListener
debe estar registrado antes
EventPublishingTestExecutionListener
.
De manera similar, si la anotación @DirtiesContext
se usa para eliminar
ApplicationContext
del caché de contexto después del último método de prueba en una clase de prueba
determinada, el AfterTestClassEvent
evento no se publicará para esta clase de prueba.
Para escuchar los eventos de ejecución de pruebas, un Spring Bean puede optar por implementar la interfaz org.springframework.context.ApplicationListener
.
Además, los métodos de escucha pueden anotarse con @EventListener
y configurarse para escuchar uno de
los tipos de eventos específicos enumerados anteriormente (consulte Oyentes
(receptores) de eventos basados en anotaciones).
Debido a la popularidad de este enfoque, Spring proporciona las siguientes anotaciones especiales @EventListener
para facilitar el registro de detectores de eventos de ejecución de pruebas. Estas anotaciones están en el paquete
org.springframework.test.context.event.annotation
.
-
@BeforeTestClass
-
@PrepareTestInstance
-
@BeforeTestMethod
-
@BeforeTestExecution
-
@AfterTestExecution
-
@AfterTestMethod
-
@AfterTestClass
Manejo de excepciones
De forma predeterminada, si un detector de eventos de ejecución de prueba genera una excepción al consumir un evento,
esa excepción se lanza al marco de prueba subyacente que se está utilizando (como JUnit o TestNG). Por ejemplo, si
consumir un evento BeforeTestMethodEvent
genera una excepción, entonces el método de prueba
correspondiente fallará como resultado de esa excepción. Por el contrario, si un detector de eventos de ejecución de
prueba asincrónica genera una excepción, no se propaga al marco de prueba subyacente. Para obtener más información
sobre el manejo de excepciones asíncrono, consulte el javadoc en @EventListener
a nivel de clase.
Oyentes asincrónicos
Si desea que un detector de eventos de ejecución de prueba específico procese eventos de forma asincrónica, puede
utilizar soporte de anotaciones
regulares @Async
de Spring.
Para obtener más detalles, consulte el javadoc en @EventListener
a nivel de clase.