Recuerda que en las ciencias informáticas un error casi siempre tiene más de una resoluciones, así que aquí te enseñamos lo mejor y más eficiente.
Solución:
Para @Async
semántica a adherirse, algunos activos @Configuration
la clase tendrá la @EnableAsync
anotación, por ejemplo
@Configuration
@EnableAsync
@EnableScheduling
public class AsyncConfiguration implements AsyncConfigurer
//
Para resolver mi problema, introduje un nuevo perfil de Spring non-async
.
Si el non-async
el perfil es no activo, el AsyncConfiguration
se utiliza:
@Configuration
@EnableAsync
@EnableScheduling
@Profile("!non-async")
public class AsyncConfiguration implements AsyncConfigurer
// this configuration will be active as long as profile "non-async" is not (!) active
Si el perfil no asíncrono es activo, el NonAsyncConfiguration
se utiliza:
@Configuration
// notice the missing @EnableAsync annotation
@EnableScheduling
@Profile("non-async")
public class NonAsyncConfiguration
// this configuration will be active as long as profile "non-async" is active
Ahora, en la clase de prueba JUnit problemática, activo explícitamente el perfil “no asíncrono” para excluir mutuamente el comportamiento asíncrono:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@IntegrationTest
@Transactional
@ActiveProfiles(profiles = "non-async")
public class SomeServiceIntTest
@Inject
private SomeService someService;
@Test
public void testAsyncMethod()
Foo testData = prepareTestData();
someService.asyncMethod(testData);
verifyResults();
// verifyResult() with assertions, etc.
Si está utilizando Mockito (directamente o a través del soporte de prueba de Spring @MockBean
), tiene un modo de verificación con un tiempo de espera exactamente para este caso: https://static.javadoc.io/org.mockito/mockito-core/2.10.0/org/mockito/Mockito.html#22
someAsyncCall();
verify(mock, timeout(100)).someMethod();
También puede usar Awaitility (lo encontré en Internet, no lo he probado). https://blog.jayway.com/2014/04/23/java-8-and-assertj-support-in-awaitility-1-6-0/
someAsyncCall();
await().until( () -> assertThat(userRepo.size()).isEqualTo(1) );
lo he hecho inyectando
ThreadPoolTaskExecutor
y luego
executor.getThreadPoolExecutor().awaitTermination(1, TimeUnit.SECONDS);
antes de verificar los resultados, de la siguiente manera:
@Autowired
private ThreadPoolTaskExecutor executor;
@Test
public void testAsyncMethod()
Foo testData = prepareTestData();
someService.asyncMethod(testData);
executor.getThreadPoolExecutor().awaitTermination(1, TimeUnit.SECONDS);
verifyResults();
Si aceptas, eres capaz de dejar un tutorial acerca de qué le añadirías a esta reseña.