He hecho una prueba de primavera de arranque para las pruebas de consumo de JMS.
La prueba es el siguiente:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
public class UpdateThingByJmsIntegrationTest {
@Test
@Rollback(false)
public void updateThingByJmsUpdatesDatabase() throws InterruptedException {
final Thing thing = new ThingBuilder().withId(null).build();
final TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
transactionTemplate.execute(transactionStatus -> {
thingRepository.save(thing);
return thing;
});
final String xml = String.format(
"<thingDto><id>%s</id><name>something else</name><location>somewhere</location></thingDto>",
thing.getId());
jmsMessagingTemplate.convertAndSend(thingUpdateQueue, xml);
Thread.sleep(1500L);
final Thing updatedThing = thingRepository.getOne(thing.getId());
assertNotNull(updatedThing);
assertEquals("something else", updatedThing.getName());
assertEquals("somewhere", updatedThing.getLocation());
}
Por lo tanto, puedo guardar una Thing
en la base de datos, a continuación, enviar un mensaje JMS para actualizar el Thing
. Dado que el consumo de JMS sucede en un hilo separado de la prueba en sí, espero, y luego tratar de verificar que la Thing
ha actualizado.
Esto funciona muy bien en IntelliJ, pero cuando se ejecuta con Maven se produce un error, debido a la rosca de consumir el mensaje JMS no ser capaz de encontrar el Thing
en la base de datos.
He tratado de dar salida al código hash objeto (identificador) del ThingRepository
tanto en la prueba y el código de consumir el mensaje JMS, y que aparezca de manera diferente. Con IntelliJ que son los mismos. Sospecho que esto podría ser parte del problema, pero no estoy seguro de cómo evitarlo.
También comprobé la salida del registro de IntelliJ vs Maven, y me parece que Maven salidas de estas líneas antes de la prueba está aún en ejecución, para IntelliJ no lo hace. No sé si es relevante.
2019-05-13 09:48:53.983 INFO 9271 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
2019-05-13 09:48:53.995 INFO 9271 --- [ main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2019-05-13 09:48:53.996 INFO 9271 --- [ main] .SchemaDropperImpl$DelayedDropActionImpl : HHH000477: Starting delayed evictData of schema as part of SessionFactory shut-down'
2019-05-13 09:48:54.000 INFO 9271 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-3 - Shutdown initiated...
2019-05-13 09:48:54.001 INFO 9271 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-3 - Shutdown completed.
Pero ¿por qué debería tener un repositorio de objetos diferentes en la prueba y la clase que se está probando?
Actualizar:
Resulta que esto sólo ocurre cuando se ejecuta la prueba de que se trate en la misma prueba como otra prueba. En esta otra prueba, que tengo:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
public class OtherIntegrationTest {
@MockBean
private ThingRepository thingRepository;
Parece que esta "hemorragias" a través de mi otra prueba, por lo que el contexto utilizan un simulacro mientras mi prueba utiliza el trato real. Cualquier forma de evitar esto, o tengo que encontrar una alternativa al uso @MockBean?
Esto podría ser causado por la falta de aislamiento adecuado de la prueba. Si la updateThingByJmsUpdatesDatabase
prueba está funcionando por sí mismo y no cuando se ejecuta como parte del conjunto de pruebas durante la construcción por ejemplo, cuando se realizan pruebas con mvn clean install
.
Se debe comprobar esto mediante la ejecución de este único ensayo usando Maven:
mvn test -Dtest=ClassName.updateThingByJmsUpdatesDatabase