|
9 | 9 | import static net.bytebuddy.matcher.ElementMatchers.named;
|
10 | 10 | import static org.assertj.core.api.Assertions.assertThat;
|
11 | 11 | import static org.assertj.core.api.Assertions.fail;
|
12 |
| -import static org.junit.Assert.assertEquals; |
13 |
| -import static org.junit.Assert.assertNotNull; |
| 12 | +import static org.junit.Assert.*; |
14 | 13 | import static org.junit.Assume.assumeTrue;
|
15 | 14 |
|
16 | 15 | import java.io.IOException;
|
17 |
| -import java.util.HashMap; |
18 |
| -import java.util.List; |
19 |
| -import java.util.Observable; |
20 |
| -import java.util.Observer; |
21 |
| -import java.util.Optional; |
22 |
| -import java.util.Set; |
| 16 | +import java.util.*; |
23 | 17 | import java.util.concurrent.Callable;
|
24 | 18 | import java.util.regex.Pattern;
|
| 19 | +import java.util.stream.Collectors; |
25 | 20 |
|
26 | 21 | import net.bytebuddy.ByteBuddy;
|
27 | 22 | import net.bytebuddy.ClassFileVersion;
|
@@ -253,48 +248,90 @@ public void should_leave_causing_stack() throws Exception {
|
253 | 248 | mockMaker.createSpy(
|
254 | 249 | settings, new MockHandlerImpl<>(settings), new ExceptionThrowingClass());
|
255 | 250 |
|
256 |
| - StackTraceElement[] returnedStack = null; |
257 |
| - try { |
258 |
| - proxy.get().throwException(); |
259 |
| - } catch (IOException ex) { |
260 |
| - returnedStack = ex.getStackTrace(); |
261 |
| - } |
| 251 | + StackTraceElement[] returnedStack = |
| 252 | + assertThrows(IOException.class, () -> proxy.get().throwException()).getStackTrace(); |
262 | 253 |
|
263 | 254 | assertNotNull("Stack trace from mockito expected", returnedStack);
|
264 | 255 |
|
265 |
| - assertEquals(ExceptionThrowingClass.class.getName(), returnedStack[0].getClassName()); |
266 |
| - assertEquals("internalThrowException", returnedStack[0].getMethodName()); |
| 256 | + List<StackTraceElement> exceptionClassElements = |
| 257 | + Arrays.stream(returnedStack) |
| 258 | + .filter( |
| 259 | + element -> |
| 260 | + element.getClassName() |
| 261 | + .equals(ExceptionThrowingClass.class.getName())) |
| 262 | + .collect(Collectors.toList()); |
| 263 | + assertEquals(3, exceptionClassElements.size()); |
| 264 | + assertEquals("internalThrowException", exceptionClassElements.get(0).getMethodName()); |
| 265 | + assertEquals("internalThrowException", exceptionClassElements.get(1).getMethodName()); |
| 266 | + assertEquals("throwException", exceptionClassElements.get(2).getMethodName()); |
| 267 | + } |
| 268 | + |
| 269 | + @Test |
| 270 | + public void should_leave_causing_stack_with_two_spies() throws Exception { |
| 271 | + // given |
| 272 | + MockSettingsImpl<ExceptionThrowingClass> settingsEx = new MockSettingsImpl<>(); |
| 273 | + settingsEx.setTypeToMock(ExceptionThrowingClass.class); |
| 274 | + settingsEx.defaultAnswer(Answers.CALLS_REAL_METHODS); |
| 275 | + Optional<ExceptionThrowingClass> proxyEx = |
| 276 | + mockMaker.createSpy( |
| 277 | + settingsEx, |
| 278 | + new MockHandlerImpl<>(settingsEx), |
| 279 | + new ExceptionThrowingClass()); |
| 280 | + |
| 281 | + MockSettingsImpl<WrapperClass> settingsWr = new MockSettingsImpl<>(); |
| 282 | + settingsWr.setTypeToMock(WrapperClass.class); |
| 283 | + settingsWr.defaultAnswer(Answers.CALLS_REAL_METHODS); |
| 284 | + Optional<WrapperClass> proxyWr = |
| 285 | + mockMaker.createSpy( |
| 286 | + settingsWr, new MockHandlerImpl<>(settingsWr), new WrapperClass()); |
| 287 | + |
| 288 | + // when |
| 289 | + IOException ex = |
| 290 | + assertThrows(IOException.class, () -> proxyWr.get().callWrapped(proxyEx.get())); |
| 291 | + List<StackTraceElement> wrapperClassElements = |
| 292 | + Arrays.stream(ex.getStackTrace()) |
| 293 | + .filter( |
| 294 | + element -> |
| 295 | + element.getClassName().equals(WrapperClass.class.getName())) |
| 296 | + .collect(Collectors.toList()); |
| 297 | + |
| 298 | + // then |
| 299 | + assertEquals(1, wrapperClassElements.size()); |
| 300 | + assertEquals("callWrapped", wrapperClassElements.get(0).getMethodName()); |
267 | 301 | }
|
268 | 302 |
|
269 | 303 | @Test
|
270 | 304 | public void should_remove_recursive_self_call_from_stack_trace() throws Exception {
|
271 | 305 | StackTraceElement[] stack =
|
272 | 306 | new StackTraceElement[] {
|
273 | 307 | new StackTraceElement("foo", "", "", -1),
|
274 |
| - new StackTraceElement(SampleInterface.class.getName(), "", "", -1), |
| 308 | + new StackTraceElement(SampleInterface.class.getName(), "", "", 15), |
275 | 309 | new StackTraceElement("qux", "", "", -1),
|
276 | 310 | new StackTraceElement("bar", "", "", -1),
|
| 311 | + new StackTraceElement(SampleInterface.class.getName(), "", "", 15), |
277 | 312 | new StackTraceElement("baz", "", "", -1)
|
278 | 313 | };
|
279 | 314 |
|
280 | 315 | Throwable throwable = new Throwable();
|
281 | 316 | throwable.setStackTrace(stack);
|
282 |
| - throwable = MockMethodAdvice.hideRecursiveCall(throwable, 2, SampleInterface.class); |
| 317 | + throwable = MockMethodAdvice.removeRecursiveCalls(throwable, SampleInterface.class); |
283 | 318 |
|
284 | 319 | assertThat(throwable.getStackTrace())
|
285 | 320 | .isEqualTo(
|
286 | 321 | new StackTraceElement[] {
|
287 | 322 | new StackTraceElement("foo", "", "", -1),
|
| 323 | + new StackTraceElement("qux", "", "", -1), |
288 | 324 | new StackTraceElement("bar", "", "", -1),
|
| 325 | + new StackTraceElement(SampleInterface.class.getName(), "", "", 15), |
289 | 326 | new StackTraceElement("baz", "", "", -1)
|
290 | 327 | });
|
291 | 328 | }
|
292 | 329 |
|
293 | 330 | @Test
|
294 |
| - public void should_handle_missing_or_inconsistent_stack_trace() throws Exception { |
| 331 | + public void should_handle_missing_or_inconsistent_stack_trace() { |
295 | 332 | Throwable throwable = new Throwable();
|
296 | 333 | throwable.setStackTrace(new StackTraceElement[0]);
|
297 |
| - assertThat(MockMethodAdvice.hideRecursiveCall(throwable, 0, SampleInterface.class)) |
| 334 | + assertThat(MockMethodAdvice.removeRecursiveCalls(throwable, SampleInterface.class)) |
298 | 335 | .isSameAs(throwable);
|
299 | 336 | }
|
300 | 337 |
|
@@ -579,6 +616,12 @@ public T value() {
|
579 | 616 | }
|
580 | 617 | }
|
581 | 618 |
|
| 619 | + public static class WrapperClass { |
| 620 | + public void callWrapped(ExceptionThrowingClass exceptionThrowingClass) throws IOException { |
| 621 | + exceptionThrowingClass.throwException(); |
| 622 | + } |
| 623 | + } |
| 624 | + |
582 | 625 | public static class GenericSubClass extends GenericClass<String> {}
|
583 | 626 |
|
584 | 627 | public static class ExceptionThrowingClass {
|
|
0 commit comments