1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.atlassian.fugue.retry;
17
18 import org.junit.Before;
19 import org.junit.Test;
20 import org.mockito.Mock;
21
22 import java.util.function.Function;
23
24 import static org.hamcrest.Matchers.equalTo;
25 import static org.junit.Assert.assertThat;
26 import static org.mockito.Matchers.anyString;
27 import static org.mockito.Mockito.times;
28 import static org.mockito.Mockito.verify;
29 import static org.mockito.Mockito.verifyNoMoreInteractions;
30 import static org.mockito.Mockito.when;
31 import static org.mockito.MockitoAnnotations.initMocks;
32
33 public class RetryFunctionTest {
34 private static final int ATTEMPTS = 4;
35
36 @Mock private Function<String, Integer> function;
37 @Mock private ExceptionHandler exceptionHandler;
38 @Mock private RuntimeException runtimeException;
39 public static final String INPUT = "1";
40 public static final Integer EXPECTED = 1;
41
42 @Before public void setUp() {
43 initMocks(this);
44 }
45
46 @Test public void basicFunction() {
47 when(function.apply(INPUT)).thenReturn(EXPECTED);
48 final Integer result = new RetryFunction<>(function, ATTEMPTS).apply(INPUT);
49
50 verify(function).apply(INPUT);
51 assertThat(result, equalTo(EXPECTED));
52 }
53
54 @Test(expected = RuntimeException.class) public void basicFunctionRetry() {
55 when(function.apply(anyString())).thenThrow(runtimeException);
56
57 try {
58 new RetryFunction<>(function, ATTEMPTS).apply(INPUT);
59 } finally {
60 verify(function, times(ATTEMPTS)).apply(INPUT);
61 }
62 }
63
64 @Test(expected = RuntimeException.class) public void functionRetryWithExceptionHandler() {
65 when(function.apply(INPUT)).thenThrow(runtimeException);
66
67 try {
68 new RetryFunction<>(function, ATTEMPTS, exceptionHandler).apply(INPUT);
69 } finally {
70 verify(function, times(ATTEMPTS)).apply(INPUT);
71 verify(exceptionHandler, times(ATTEMPTS)).handle(runtimeException);
72 }
73 }
74
75 @Test public void functionEarlyExit() {
76 when(function.apply(INPUT)).thenThrow(new RuntimeException("First attempt")).thenReturn(EXPECTED)
77 .thenThrow(new RuntimeException("Third attempt")).thenThrow(new RuntimeException("Fourth attempt"));
78
79 final Integer result = new RetryFunction<>(function, ATTEMPTS).apply(INPUT);
80 assertThat(result, equalTo(EXPECTED));
81 verify(function, times(2)).apply(INPUT);
82 verifyNoMoreInteractions(function);
83 }
84
85 @Test(expected = IllegalArgumentException.class) public void cannotSupplyNegativeRetries() {
86 new RetryFunction<>(function, -1);
87 }
88 }