View Javadoc
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      // given
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      // when
61      try {
62        breakHandler.onBreak(circuitBreaker, task, breakStrategy, executionContext);
63      } catch (Exception e) {
64        // then
65        assertThat(e.getClass(), equalTo(BreakHandlerException.class));
66        assertThat(e.getCause(), is(notNullValue()));
67        assertThat(e.getCause().getClass(), equalTo(InvocationTargetException.class)); // problem with constructing class via constructor
68        assertThat(((InvocationTargetException) e.getCause()).getTargetException().getClass(),
69          equalTo(BreakHandlerTestInstantiationException.class)); // problem with constructing class via constructor
70      }
71    }
72  
73    @Test
74    public void shouldThrowBreakHandlerExceptionWithCustomMessageWhenMessageCallbackIsProvided() {
75      // given
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      // when
88      try {
89        breakHandler.onBreak(circuitBreaker, task, breakStrategy, executionContext);
90      } catch (Exception e) {
91        // then
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      // when
98      try {
99        breakHandler.onBreak(circuitBreaker, task, breakStrategy, executionContext);
100     } catch (Exception e) {
101       // then
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     // given
112 
113     // IOException is not instance of BreakHandlerExceptin
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     // when
126     try {
127       breakHandler.onBreak(circuitBreaker, task, breakStrategy, executionContext);
128     } catch (Exception e) {
129       // then
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     // given
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     // when
158     try {
159       breakHandler.onBreak(circuitBreaker, task, breakStrategy, executionContext);
160     } catch (Exception e) {
161       // then
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 }