2525import java .util .concurrent .Executor ;
2626import java .util .concurrent .Executors ;
2727import java .util .concurrent .Future ;
28+ import java .util .concurrent .TimeUnit ;
2829
30+ import org .awaitility .Awaitility ;
2931import org .junit .Test ;
3032import org .mockito .Mockito ;
3133
@@ -163,7 +165,7 @@ public void customAsyncAnnotationIsPropagated() {
163165 Object bean = ctx .getBean (CustomAsyncBean .class );
164166 assertTrue (AopUtils .isAopProxy (bean ));
165167 boolean isAsyncAdvised = false ;
166- for (Advisor advisor : ((Advised )bean ).getAdvisors ()) {
168+ for (Advisor advisor : ((Advised ) bean ).getAdvisors ()) {
167169 if (advisor instanceof AsyncAnnotationAdvisor ) {
168170 isAsyncAdvised = true ;
169171 break ;
@@ -184,85 +186,129 @@ public void aspectModeAspectJAttemptsToRegisterAsyncAspect() {
184186
185187 @ Test
186188 public void customExecutorBean () throws InterruptedException {
189+ // Arrange
187190 AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext ();
188191 ctx .register (CustomExecutorBean .class );
189192 ctx .refresh ();
190-
191193 AsyncBean asyncBean = ctx .getBean (AsyncBean .class );
194+ // Act
192195 asyncBean .work ();
193- Thread .sleep (500 );
196+ // Assert
197+ Awaitility .await ()
198+ .atMost (500 , TimeUnit .MILLISECONDS )
199+ .pollInterval (10 , TimeUnit .MILLISECONDS )
200+ .until (() -> asyncBean .getThreadOfExecution () != null );
194201 assertThat (asyncBean .getThreadOfExecution ().getName (), startsWith ("Custom-" ));
195-
196202 ctx .close ();
197203 }
198204
199205 @ Test
200206 public void customExecutorConfig () throws InterruptedException {
207+ // Arrange
201208 AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext ();
202209 ctx .register (CustomExecutorConfig .class );
203210 ctx .refresh ();
204-
205211 AsyncBean asyncBean = ctx .getBean (AsyncBean .class );
212+ // Act
206213 asyncBean .work ();
207- Thread .sleep (500 );
214+ // Assert
215+ Awaitility .await ()
216+ .atMost (500 , TimeUnit .MILLISECONDS )
217+ .pollInterval (10 , TimeUnit .MILLISECONDS )
218+ .until (() -> asyncBean .getThreadOfExecution () != null );
208219 assertThat (asyncBean .getThreadOfExecution ().getName (), startsWith ("Custom-" ));
220+ ctx .close ();
221+ }
209222
210- TestableAsyncUncaughtExceptionHandler exceptionHandler = (TestableAsyncUncaughtExceptionHandler )
211- ctx .getBean ("exceptionHandler" );
223+ @ Test
224+ public void customExecutorConfigWithThrowsException () {
225+ // Arrange
226+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext ();
227+ ctx .register (CustomExecutorConfig .class );
228+ ctx .refresh ();
229+ AsyncBean asyncBean = ctx .getBean (AsyncBean .class );
230+ Method method = ReflectionUtils .findMethod (AsyncBean .class , "fail" );
231+ TestableAsyncUncaughtExceptionHandler exceptionHandler =
232+ (TestableAsyncUncaughtExceptionHandler ) ctx .getBean ("exceptionHandler" );
212233 assertFalse ("handler should not have been called yet" , exceptionHandler .isCalled ());
213-
234+ // Act
214235 asyncBean .fail ();
215- Thread .sleep (500 );
216- Method method = ReflectionUtils .findMethod (AsyncBean .class , "fail" );
217- exceptionHandler .assertCalledWith (method , UnsupportedOperationException .class );
218-
236+ // Assert
237+ Awaitility .await ()
238+ .pollInterval (10 , TimeUnit .MILLISECONDS )
239+ .atMost (500 , TimeUnit .MILLISECONDS )
240+ .untilAsserted (() -> exceptionHandler .assertCalledWith (method , UnsupportedOperationException .class ));
219241 ctx .close ();
220242 }
221243
222244 @ Test
223245 public void customExecutorBeanConfig () throws InterruptedException {
246+ // Arrange
224247 AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext ();
225248 ctx .register (CustomExecutorBeanConfig .class , ExecutorPostProcessor .class );
226249 ctx .refresh ();
227-
228250 AsyncBean asyncBean = ctx .getBean (AsyncBean .class );
251+ // Act
229252 asyncBean .work ();
230- Thread .sleep (500 );
253+ // Assert
254+ Awaitility .await ()
255+ .pollInterval (10 , TimeUnit .MILLISECONDS )
256+ .atMost (500 , TimeUnit .MILLISECONDS )
257+ .until (() -> asyncBean .getThreadOfExecution () != null );
231258 assertThat (asyncBean .getThreadOfExecution ().getName (), startsWith ("Post-" ));
259+ ctx .close ();
260+ }
232261
233- TestableAsyncUncaughtExceptionHandler exceptionHandler = (TestableAsyncUncaughtExceptionHandler )
234- ctx .getBean ("exceptionHandler" );
262+ @ Test
263+ public void customExecutorBeanConfigWithThrowsException () {
264+ // Arrange
265+ AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext ();
266+ ctx .register (CustomExecutorBeanConfig .class , ExecutorPostProcessor .class );
267+ ctx .refresh ();
268+ AsyncBean asyncBean = ctx .getBean (AsyncBean .class );
269+ TestableAsyncUncaughtExceptionHandler exceptionHandler =
270+ (TestableAsyncUncaughtExceptionHandler ) ctx .getBean ("exceptionHandler" );
235271 assertFalse ("handler should not have been called yet" , exceptionHandler .isCalled ());
236-
237- asyncBean .fail ();
238- Thread .sleep (500 );
239272 Method method = ReflectionUtils .findMethod (AsyncBean .class , "fail" );
240- exceptionHandler .assertCalledWith (method , UnsupportedOperationException .class );
241-
273+ // Act
274+ asyncBean .fail ();
275+ // Assert
276+ Awaitility .await ()
277+ .atMost (500 , TimeUnit .MILLISECONDS )
278+ .pollInterval (10 , TimeUnit .MILLISECONDS )
279+ .untilAsserted (() -> exceptionHandler .assertCalledWith (method , UnsupportedOperationException .class ));
242280 ctx .close ();
243281 }
244282
245283 @ Test // SPR-14949
246284 public void findOnInterfaceWithInterfaceProxy () throws InterruptedException {
285+ // Arrange
247286 AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext (Spr14949ConfigA .class );
248-
249287 AsyncInterface asyncBean = ctx .getBean (AsyncInterface .class );
288+ // Act
250289 asyncBean .work ();
251- Thread .sleep (500 );
290+ // Assert
291+ Awaitility .await ()
292+ .atMost (500 , TimeUnit .MILLISECONDS )
293+ .pollInterval (10 , TimeUnit .MILLISECONDS )
294+ .until (() -> asyncBean .getThreadOfExecution () != null );
252295 assertThat (asyncBean .getThreadOfExecution ().getName (), startsWith ("Custom-" ));
253-
254296 ctx .close ();
255297 }
256298
257299 @ Test // SPR-14949
258300 public void findOnInterfaceWithCglibProxy () throws InterruptedException {
301+ // Arrange
259302 AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext (Spr14949ConfigB .class );
260-
261303 AsyncInterface asyncBean = ctx .getBean (AsyncInterface .class );
304+ // Act
262305 asyncBean .work ();
263- Thread .sleep (500 );
306+ // Assert
307+ Awaitility .await ()
308+ .atMost (500 , TimeUnit .MILLISECONDS )
309+ .pollInterval (10 , TimeUnit .MILLISECONDS )
310+ .until (()-> asyncBean .getThreadOfExecution () != null );
264311 assertThat (asyncBean .getThreadOfExecution ().getName (), startsWith ("Custom-" ));
265-
266312 ctx .close ();
267313 }
268314
@@ -390,7 +436,8 @@ public AsyncBean asyncBean() {
390436 @ EnableAsync
391437 static class AsyncConfigWithMockito {
392438
393- @ Bean @ Lazy
439+ @ Bean
440+ @ Lazy
394441 public AsyncBean asyncBean () {
395442 return Mockito .mock (AsyncBean .class );
396443 }
0 commit comments