Probar los methods @Async de devolución de vacío de Testing
Tengo un pequeño problema con los methods @Async
que devuelven el void
(o Unit
, estoy escribiendo en Kotlin) en mi aplicación Spring.
No sé por qué, pero cuando el método @Async
devuelve void
, simplemente no se ejecuta, o al less no hace lo que se supone que debe. Necesito decir que en mis methods asíncronos, quiero enviar un correo electrónico usando JavaMailSender
, por lo que no es gran cosa. Este es el método:
- cómo cargar config en spring-webflux sin spring-boot?
- Integración de HTML y CSS con Kotlin y Spring MVC
- Spring MVC Error 404 Bad Request Kotlin
- No se puede conectar a Remote Mongo DB mediante Springboot
- use kotlin para springmvc No se pudo crear una instancia de la class de datos de la class bean
@Async override fun sendEmail(locale: Locale, subject: String, message: String, to: String) { val msg = sender.createMimeMessage() println("1") val helper = MimeMessageHelper(msg, true, "utf-8") helper.setFrom("email@example.com") helper.setTo(to) println("2") helper.setSubject(getSubject(locale, null)) println("3") helper.setText(processTemplate(locale, null, null), true) println("4") sender.send(msg) println("5") }
Pero nunca llega un correo electrónico, no hay una exception registrada (estoy ejecutando una testing testNG).
Cuando cambio la firma de la function para que devuelva Future<String>
y agregue alguna línea ficticia de retorno al final de la function y luego llamo a service.sendEmail(...).get()
, el cuerpo del método se ejecuta mágicamente y llega el correo electrónico.
En mi class @Configuration
, hay @EnableAsync
. También implementé AsyncConfigurer
y proporcioné el propio ejecutor y manejador de excepciones, porque pensé que podría haber sido algo con mi definición de bean ejecutor, pero nada ayuda.
Esto me está volviendo loco, porque solo quiero ejecutar en silencio algo en el background y no funciona. En silencio quiero decir que no quiero ser molestado por las excepciones arrojadas dentro.
¿Tienes alguna idea?
Actualización: Entonces, como @pleft aconsejó, puse algunas impresiones dentro de mi método. Ahora, cuando ejecuto mvn clean test
, puedo ver que 1,2,3 están impresos, pero no cada vez. Algunas veces solo se imprimieron 1 y 2. También puse la printing en mi AsyncUncaughtExceptionHandler
, pero ese no se llama. Parece que el hilo de background se está matando demasiado pronto o algo así.
Actualización 2:
Mi ServiceConfig:
@Configuration @EnableScheduling @EnableAsync @ComponentScan class ServiceConfig : ApplicationContextAware, EnvironmentAware, AsyncConfigurer { override fun getAsyncUncaughtExceptionHandler(): AsyncUncaughtExceptionHandler { return AsyncUncaughtExceptionHandler { ex, method, params -> println("Exception thrown") } } override fun getAsyncExecutor(): Executor { val executor = ThreadPoolTaskExecutor() executor.corePoolSize = 2 executor.maxPoolSize = 2 executor.setQueueCapacity(500) executor.threadNamePrefix = "asyncThread" executor.initialize() return executor } } /// other beans definitions..
Tal vez es importante, tal vez no, pero estoy usando Thymeleaf en ese método processTemplate
.
- ¿No se necesita NotNull en Kotlin?
- Crear un propio DataSource con properties de resorte
- Spring Data JPA / Hibernate "No se puede ubicar Attribute con el nombre de stack"
- Spring Boot e Hibernate. Manejar la fábrica de sesiones
- No se puede publicar contenido web dynamic con Spring Boot y Kotlin
- Excepción de puntero nulo en Spring Proxy Class y Kotlin
- Tenga la security de que multiparte es nulo en el controller de descanso
- Validación de Java Bean en Spring MVC Controller PathVariables
Basado en la conversación en el comentario y mi propia observación (como dormir un poco en el método de testing) descubrí el motivo. Esto fue causado por la destrucción del Context de Primavera dentro de la testing. Debido a que solo tenía una testing que ejecutaba este método asíncrono, el escenario era que el método asíncrono regresaba inmediatamente y también lo hacía el método de testing. Como era el último (y único) método en mi set de testings, el Context de testing se destruyó (y también todos los hilos que creó).
Por lo tanto, la resolución es poner suspensiones en las testings (muy feo) o echar un vistazo a esta pregunta e inspirarse.
- Spring Boot: Boot Run no puede agregar addResources = true
- Cómo exportar funciones de Kotlin a Javascript con el nombre correcto