1 /*
2  * Copyright (c) 2007 Mockito contributors
3  * This program is made available under the terms of the MIT License.
4  */
5 package org.mockito.internal.handler;
6 
7 import org.junit.Before;
8 import org.junit.Test;
9 import org.junit.runner.RunWith;
10 import org.mockito.ArgumentMatchers;
11 import org.mockito.Mock;
12 import org.mockito.Spy;
13 import org.mockito.exceptions.base.MockitoException;
14 import org.mockito.internal.creation.MockSettingsImpl;
15 import org.mockito.invocation.Invocation;
16 import org.mockito.listeners.InvocationListener;
17 import org.mockito.listeners.MethodInvocationReport;
18 import org.mockito.mock.MockCreationSettings;
19 import org.mockito.junit.MockitoJUnitRunner;
20 import org.mockito.stubbing.Answer;
21 
22 import java.text.ParseException;
23 import java.util.ArrayList;
24 
25 import static org.assertj.core.api.Assertions.assertThat;
26 import static org.junit.Assert.fail;
27 import static org.mockito.BDDMockito.given;
28 import static org.mockito.BDDMockito.willThrow;
29 import static org.mockito.Matchers.any;
30 import static org.mockito.Mockito.mock;
31 import static org.mockito.Mockito.verify;
32 
33 
34 @RunWith(MockitoJUnitRunner.class)
35 @SuppressWarnings("unchecked")
36 public class InvocationNotifierHandlerTest {
37     private static final String SOME_LOCATION = "some location";
38     private static final RuntimeException SOME_EXCEPTION = new RuntimeException();
39     private static final OutOfMemoryError SOME_ERROR = new OutOfMemoryError();
40     private static final Answer<?> SOME_ANSWER = mock(Answer.class);
41 
42 
43     @Mock private InvocationListener listener1;
44     @Mock private InvocationListener listener2;
45     @Spy private CustomListener customListener;
46 
47     @Mock private Invocation invocation;
48     @Mock private MockHandlerImpl<ArrayList<Answer<?>>> mockHandler;
49 
50     private InvocationNotifierHandler<ArrayList<Answer<?>>> notifier;
51 
52     @Before
setUp()53     public void setUp() throws Exception {
54         notifier = new InvocationNotifierHandler<ArrayList<Answer<?>>>(
55                 mockHandler,
56                 (MockCreationSettings<ArrayList<Answer<?>>>) new MockSettingsImpl<ArrayList<Answer<?>>>().invocationListeners(customListener, listener1, listener2)
57         );
58     }
59 
60     @Test
should_notify_all_listeners_when_calling_delegate_handler()61     public void should_notify_all_listeners_when_calling_delegate_handler() throws Throwable {
62         // given
63         given(mockHandler.handle(invocation)).willReturn("returned value");
64 
65         // when
66         notifier.handle(invocation);
67 
68         // then
69         verify(listener1).reportInvocation(new NotifiedMethodInvocationReport(invocation, "returned value"));
70         verify(listener2).reportInvocation(new NotifiedMethodInvocationReport(invocation, "returned value"));
71     }
72 
73     @Test
should_notify_all_listeners_when_called_delegate_handler_returns_ex()74     public void should_notify_all_listeners_when_called_delegate_handler_returns_ex() throws Throwable {
75         // given
76         Exception computedException = new Exception("computed");
77         given(mockHandler.handle(invocation)).willReturn(computedException);
78 
79         // when
80         notifier.handle(invocation);
81 
82         // then
83         verify(listener1).reportInvocation(new NotifiedMethodInvocationReport(invocation, (Object) computedException));
84         verify(listener2).reportInvocation(new NotifiedMethodInvocationReport(invocation, (Object) computedException));
85     }
86 
87     @Test(expected = ParseException.class)
should_notify_all_listeners_when_called_delegate_handler_throws_exception_and_rethrow_it()88     public void should_notify_all_listeners_when_called_delegate_handler_throws_exception_and_rethrow_it() throws Throwable {
89         // given
90         ParseException parseException = new ParseException("", 0);
91         given(mockHandler.handle(invocation)).willThrow(parseException);
92 
93         // when
94         try {
95             notifier.handle(invocation);
96             fail();
97         } finally {
98             // then
99             verify(listener1).reportInvocation(new NotifiedMethodInvocationReport(invocation, parseException));
100             verify(listener2).reportInvocation(new NotifiedMethodInvocationReport(invocation, parseException));
101         }
102     }
103 
104     @Test
should_report_listener_exception()105     public void should_report_listener_exception() throws Throwable {
106         willThrow(new NullPointerException()).given(customListener).reportInvocation(any(MethodInvocationReport.class));
107 
108         try {
109             notifier.handle(invocation);
110             fail();
111         } catch (MockitoException me) {
112             assertThat(me.getMessage())
113                     .contains("invocation listener")
114                     .contains("CustomListener")
115                     .contains("threw an exception")
116                     .contains("NullPointerException");
117         }
118     }
119 
120     @Test
should_delegate_all_MockHandlerInterface_to_the_parameterized_MockHandler()121     public void should_delegate_all_MockHandlerInterface_to_the_parameterized_MockHandler() throws Exception {
122         notifier.getInvocationContainer();
123         notifier.getMockSettings();
124         notifier.setAnswersForStubbing(new ArrayList<Answer<?>>());
125 
126         verify(mockHandler).getInvocationContainer();
127         verify(mockHandler).getMockSettings();
128         verify(mockHandler).setAnswersForStubbing(ArgumentMatchers.<Answer<?>>anyList());
129     }
130 
131     private static class CustomListener implements InvocationListener {
reportInvocation(MethodInvocationReport methodInvocationReport)132         public void reportInvocation(MethodInvocationReport methodInvocationReport) {
133             // nop
134         }
135     }
136 }
137