2020import  java .io .IOException ;
2121import  java .time .Duration ;
2222import  java .util .List ;
23+ import  java .util .Objects ;
2324import  java .util .concurrent .atomic .AtomicInteger ;
2425import  java .util .function .Consumer ;
2526
3940import  static  org .mockito .Mockito .inOrder ;
4041import  static  org .mockito .Mockito .mock ;
4142import  static  org .mockito .Mockito .verifyNoInteractions ;
43+ import  static  org .mockito .Mockito .verifyNoMoreInteractions ;
4244
4345/** 
4446 * Integration tests for {@link RetryTemplate}, {@link RetryPolicy} and 
@@ -87,11 +89,10 @@ void retryWithImmediateSuccess() throws Exception {
8789
8890	@ Test 
8991	void  retryWithSuccessAfterInitialFailures () throws  Exception  {
90- 		Exception  exception  = new  Exception ("Boom!" );
9192		AtomicInteger  invocationCount  = new  AtomicInteger ();
9293		Retryable <String > retryable  = () -> {
9394			if  (invocationCount .incrementAndGet () <= 2 ) {
94- 				throw  exception ;
95+ 				throw  new   CustomException ( "Boom "  +  invocationCount . get ()) ;
9596			}
9697			return  "finally succeeded" ;
9798		};
@@ -102,22 +103,20 @@ void retryWithSuccessAfterInitialFailures() throws Exception {
102103
103104		// RetryListener interactions: 
104105		inOrder .verify (retryListener ).beforeRetry (retryPolicy , retryable );
105- 		inOrder .verify (retryListener ).onRetryFailure (retryPolicy , retryable , exception );
106+ 		inOrder .verify (retryListener ).onRetryFailure (retryPolicy , retryable , new   CustomException ( "Boom 2" ) );
106107		inOrder .verify (retryListener ).beforeRetry (retryPolicy , retryable );
107108		inOrder .verify (retryListener ).onRetrySuccess (retryPolicy , retryable , "finally succeeded" );
108- 		inOrder . verifyNoMoreInteractions ();
109+ 		verifyNoMoreInteractions (retryListener );
109110	}
110111
111112	@ Test 
112113	void  retryWithExhaustedPolicy () {
113114		var  invocationCount  = new  AtomicInteger ();
114- 		var  exception  = new  RuntimeException ("Boom!" );
115115
116116		var  retryable  = new  Retryable <>() {
117117			@ Override 
118118			public  String  execute () {
119- 				invocationCount .incrementAndGet ();
120- 				throw  exception ;
119+ 				throw  new  CustomException ("Boom "  + invocationCount .incrementAndGet ());
121120			}
122121
123122			@ Override 
@@ -130,17 +129,19 @@ public String getName() {
130129		assertThatExceptionOfType (RetryException .class )
131130				.isThrownBy (() -> retryTemplate .execute (retryable ))
132131				.withMessage ("Retry policy for operation 'test' exhausted; aborting execution" )
133- 				.withCause (exception );
132+ 				.withCause (new   CustomException ( "Boom 4" ) );
134133		// 4 = 1 initial invocation + 3 retry attempts 
135134		assertThat (invocationCount ).hasValue (4 );
136135
137136		// RetryListener interactions: 
137+ 		invocationCount .set (1 );
138138		repeat (3 , () -> {
139139			inOrder .verify (retryListener ).beforeRetry (retryPolicy , retryable );
140- 			inOrder .verify (retryListener ).onRetryFailure (retryPolicy , retryable , exception );
140+ 			inOrder .verify (retryListener ).onRetryFailure (retryPolicy , retryable ,
141+ 					new  CustomException ("Boom "  + invocationCount .incrementAndGet ()));
141142		});
142- 		inOrder .verify (retryListener ).onRetryPolicyExhaustion (retryPolicy , retryable , exception );
143- 		inOrder . verifyNoMoreInteractions ();
143+ 		inOrder .verify (retryListener ).onRetryPolicyExhaustion (retryPolicy , retryable , new   CustomException ( "Boom 4" ) );
144+ 		verifyNoMoreInteractions (retryListener );
144145	}
145146
146147	@ Test 
@@ -184,7 +185,7 @@ public String getName() {
184185			inOrder .verify (retryListener ).onRetryFailure (retryPolicy , retryable , exception );
185186		});
186187		inOrder .verify (retryListener ).onRetryPolicyExhaustion (retryPolicy , retryable , exception );
187- 		inOrder . verifyNoMoreInteractions ();
188+ 		verifyNoMoreInteractions (retryListener );
188189	}
189190
190191	@ Test 
@@ -231,11 +232,11 @@ public String getName() {
231232		// RetryListener interactions: 
232233		repeat (2 , () -> {
233234			inOrder .verify (retryListener ).beforeRetry (retryPolicy , retryable );
234- 			inOrder .verify (retryListener ).onRetryFailure (eq (retryPolicy ), eq (retryable ), any (Throwable .class ));
235+ 			inOrder .verify (retryListener ).onRetryFailure (eq (retryPolicy ), eq (retryable ), any (Exception .class ));
235236		});
236237		inOrder .verify (retryListener ).onRetryPolicyExhaustion (
237238				eq (retryPolicy ), eq (retryable ), any (IllegalStateException .class ));
238- 		inOrder . verifyNoMoreInteractions ();
239+ 		verifyNoMoreInteractions (retryListener );
239240	}
240241
241242	static  final  List <ArgumentSet > includesAndExcludesRetryPolicies  = List .of (
@@ -293,11 +294,11 @@ public String getName() {
293294		// RetryListener interactions: 
294295		repeat (2 , () -> {
295296			inOrder .verify (retryListener ).beforeRetry (retryPolicy , retryable );
296- 			inOrder .verify (retryListener ).onRetryFailure (eq (retryPolicy ), eq (retryable ), any (Throwable .class ));
297+ 			inOrder .verify (retryListener ).onRetryFailure (eq (retryPolicy ), eq (retryable ), any (IOException .class ));
297298		});
298299		inOrder .verify (retryListener ).onRetryPolicyExhaustion (
299300				eq (retryPolicy ), eq (retryable ), any (CustomFileNotFoundException .class ));
300- 		inOrder . verifyNoMoreInteractions ();
301+ 		verifyNoMoreInteractions (retryListener );
301302	}
302303
303304
@@ -318,4 +319,27 @@ private static final Consumer<Throwable> hasSuppressedExceptionsSatisfyingExactl
318319	private  static  class  CustomFileNotFoundException  extends  FileNotFoundException  {
319320	}
320321
322+ 	/** 
323+ 	 * Custom {@link RuntimeException} that implements {@link #equals(Object)} 
324+ 	 * and {@link #hashCode()} for use in assertions that check for equality. 
325+ 	 */ 
326+ 	@ SuppressWarnings ("serial" )
327+ 	private  static  class  CustomException  extends  RuntimeException  {
328+ 
329+ 		CustomException (String  message ) {
330+ 			super (message );
331+ 		}
332+ 
333+ 		@ Override 
334+ 		public  int  hashCode () {
335+ 			return  Objects .hash (getMessage ());
336+ 		}
337+ 
338+ 		@ Override 
339+ 		public  boolean  equals (Object  other ) {
340+ 			return  (this  == other  ||
341+ 					(other  instanceof  CustomException  that  && getMessage ().equals (that .getMessage ())));
342+ 		}
343+ 	}
344+ 
321345}
0 commit comments