1 package net.secodo.jcircuitbreaker.breakhandler.impl;
2
3 import net.secodo.jcircuitbreaker.breaker.ContextAwareCircuitBreaker;
4 import net.secodo.jcircuitbreaker.breakhandler.exception.BreakHandlerException;
5 import net.secodo.jcircuitbreaker.breakstrategy.BreakStrategy;
6 import net.secodo.jcircuitbreaker.task.Task;
7 import org.junit.Test;
8 import net.secodo.jcircuitbreaker.breaker.CircuitBreaker;
9 import net.secodo.jcircuitbreaker.breaker.execution.ExecutionContext;
10
11 import java.io.IOException;
12 import java.lang.reflect.InvocationTargetException;
13 import java.util.concurrent.Callable;
14 import static org.hamcrest.CoreMatchers.equalTo;
15 import static org.hamcrest.CoreMatchers.nullValue;
16 import static org.hamcrest.core.Is.is;
17 import static org.hamcrest.core.IsInstanceOf.instanceOf;
18 import static org.hamcrest.core.IsNull.notNullValue;
19 import static org.junit.Assert.assertThat;
20 import static org.mockito.Mockito.mock;
21 import static org.mockito.Mockito.when;
22
23
24 @SuppressWarnings("unchecked")
25 public class ExceptionThrowingHandlerTest {
26 @Test
27 public void shouldThrowBreakHandlerExceptionWhenJustMessageIsGivenAsConstructorParam() {
28 final ExecutionContext<Short> executionContext = mock(ExecutionContext.class);
29 final String exceptionMessage = "Expected test exception occurred while executing test task";
30 final ExceptionThrowingHandler<Short> breakHandler = new ExceptionThrowingHandler(
31 exceptionMessage);
32
33
34 final ContextAwareCircuitBreaker<Short> circuitBreaker = mock(ContextAwareCircuitBreaker.class);
35 final BreakStrategy<Short> breakStrategy = mock(BreakStrategy.class);
36 final Task<Short> task = mock(Task.class);
37
38 try {
39 breakHandler.onBreak(circuitBreaker, task, breakStrategy, executionContext);
40 } catch (BreakHandlerException e) {
41 assertThat(e.getClass(), equalTo(BreakHandlerException.class));
42 assertThat(e.getCause(), is(nullValue()));
43 assertThat(e.getMessage(), equalTo(exceptionMessage));
44 }
45 }
46
47 @Test
48 public void shouldThrowBreakHandlerExceptionInCaseGivenExceptionClassConstructionResultsInException() {
49
50 final ExecutionContext<Long> executionContext = mock(ExecutionContext.class);
51 final ExceptionThrowingHandler<Long> breakHandler = new ExceptionThrowingHandler(
52 BreakHandlerTestNotWorkingException.class,
53 "Test exception occurred while executing test task");
54
55
56 final ContextAwareCircuitBreaker<Long> circuitBreaker = mock(ContextAwareCircuitBreaker.class);
57 final BreakStrategy<Long> breakStrategy = mock(BreakStrategy.class);
58 final Task<Long> task = mock(Task.class);
59
60
61 try {
62 breakHandler.onBreak(circuitBreaker, task, breakStrategy, executionContext);
63 } catch (Exception e) {
64
65 assertThat(e.getClass(), equalTo(BreakHandlerException.class));
66 assertThat(e.getCause(), is(notNullValue()));
67 assertThat(e.getCause().getClass(), equalTo(InvocationTargetException.class));
68 assertThat(((InvocationTargetException) e.getCause()).getTargetException().getClass(),
69 equalTo(BreakHandlerTestInstantiationException.class));
70 }
71 }
72
73 @Test
74 public void shouldThrowBreakHandlerExceptionWithCustomMessageWhenMessageCallbackIsProvided() {
75
76 final ExceptionThrowingHandler<Long> breakHandler = new ExceptionThrowingHandler(((task, execContext) -> "My " +
77 "custom message " + execContext.getContextAttribute("messageId")
78 ));
79
80 final ExecutionContext executionContext = mock(ExecutionContext.class);
81 when(executionContext.getContextAttribute("messageId")).thenReturn("A").thenReturn("B");
82
83 final ContextAwareCircuitBreaker circuitBreaker = mock(ContextAwareCircuitBreaker.class);
84 final BreakStrategy breakStrategy = mock(BreakStrategy.class);
85 final Task task = mock(Task.class);
86
87
88 try {
89 breakHandler.onBreak(circuitBreaker, task, breakStrategy, executionContext);
90 } catch (Exception e) {
91
92 assertThat(e.getClass(), equalTo(BreakHandlerException.class));
93 assertThat(e.getCause(), is(nullValue()));
94 assertThat(e.getMessage(), equalTo("My custom message A"));
95 }
96
97
98 try {
99 breakHandler.onBreak(circuitBreaker, task, breakStrategy, executionContext);
100 } catch (Exception e) {
101
102 assertThat(e.getClass(), equalTo(BreakHandlerException.class));
103 assertThat(e.getCause(), is(nullValue()));
104 assertThat(e.getMessage(), equalTo("My custom message B"));
105 }
106 }
107
108
109 @Test
110 public void shouldThrowBreakHandlerExceptionWhenCustomExceptionIsNotInstanceOfBreakHandlerException() {
111
112
113
114 final ExceptionThrowingHandler<Long> breakHandler = new ExceptionThrowingHandler(IOException.class,
115 ((task, execContext) -> "My custom message " + execContext.getContextAttribute("messageId")
116 ));
117
118 final ExecutionContext executionContext = mock(ExecutionContext.class);
119 when(executionContext.getContextAttribute("messageId")).thenReturn("A").thenReturn("B");
120
121 final ContextAwareCircuitBreaker circuitBreaker = mock(ContextAwareCircuitBreaker.class);
122 final BreakStrategy breakStrategy = mock(BreakStrategy.class);
123 final Task task = mock(Task.class);
124
125
126 try {
127 breakHandler.onBreak(circuitBreaker, task, breakStrategy, executionContext);
128 } catch (Exception e) {
129
130 assertThat(e.getClass(), equalTo(BreakHandlerException.class));
131 assertThat(e.getCause(), is(notNullValue()));
132 assertThat(e.getCause(), instanceOf(ClassCastException.class));
133 assertThat(e.getMessage(), equalTo("Unable to throw custom exception of class: " + IOException.class +
134 " and message: " + "My custom message A"));
135 }
136
137 }
138
139
140 @Test
141 public void shouldThrowCustomExceptionWhenDefinedAndUseCustomMessageWhenMessageCallbackIsProvided() {
142
143
144
145
146 final ExceptionThrowingHandler<Long> breakHandler = new ExceptionThrowingHandler(ExceptionThrowingHandlerTestMyException.class,
147 ((task, execContext) -> "My custom message " + execContext.getContextAttribute("messageId")
148 ));
149
150 final ExecutionContext executionContext = mock(ExecutionContext.class);
151 when(executionContext.getContextAttribute("messageId")).thenReturn("A").thenReturn("B");
152
153 final ContextAwareCircuitBreaker circuitBreaker = mock(ContextAwareCircuitBreaker.class);
154 final BreakStrategy breakStrategy = mock(BreakStrategy.class);
155 final Task task = mock(Task.class);
156
157
158 try {
159 breakHandler.onBreak(circuitBreaker, task, breakStrategy, executionContext);
160 } catch (Exception e) {
161
162 assertThat(e.getClass(), equalTo(ExceptionThrowingHandlerTestMyException.class));
163 assertThat(e.getCause(), is(nullValue()));
164 assertThat(e.getMessage(), equalTo("My custom message A"));
165 }
166
167 }
168
169
170 }