1 /*
2  * Copyright (c) 2007 Mockito contributors
3  * This program is made available under the terms of the MIT License.
4  */
5 
6 package org.mockito.internal.handler;
7 
8 import org.junit.Test;
9 import org.mockito.exceptions.base.MockitoException;
10 import org.mockito.exceptions.misusing.InvalidUseOfMatchersException;
11 import org.mockito.exceptions.misusing.WrongTypeOfReturnValue;
12 import org.mockito.internal.creation.MockSettingsImpl;
13 import org.mockito.internal.invocation.InvocationBuilder;
14 import org.mockito.internal.invocation.InvocationMatcher;
15 import org.mockito.internal.invocation.MatchersBinder;
16 import org.mockito.internal.progress.ArgumentMatcherStorage;
17 import org.mockito.internal.stubbing.InvocationContainerImpl;
18 import org.mockito.internal.stubbing.StubbedInvocationMatcher;
19 import org.mockito.internal.stubbing.answers.Returns;
20 import org.mockito.internal.verification.VerificationModeFactory;
21 import org.mockito.invocation.Invocation;
22 import org.mockito.listeners.InvocationListener;
23 import org.mockito.listeners.MethodInvocationReport;
24 import org.mockitoutil.TestBase;
25 
26 import java.util.Arrays;
27 
28 import static org.junit.Assert.assertNull;
29 import static org.junit.Assert.fail;
30 import static org.mockito.BDDMockito.given;
31 import static org.mockito.Matchers.any;
32 import static org.mockito.Mockito.doThrow;
33 import static org.mockito.Mockito.mock;
34 import static org.mockito.internal.progress.ThreadSafeMockingProgress.mockingProgress;
35 
36 @SuppressWarnings({"unchecked", "serial"})
37 public class MockHandlerImplTest extends TestBase {
38 
39     private StubbedInvocationMatcher stubbedInvocationMatcher = mock(StubbedInvocationMatcher.class);
40     private Invocation invocation = mock(Invocation.class);
41 
42     @Test
should_remove_verification_mode_even_when_invalid_matchers()43     public void should_remove_verification_mode_even_when_invalid_matchers() throws Throwable {
44         // given
45         Invocation invocation = new InvocationBuilder().toInvocation();
46         @SuppressWarnings("rawtypes")
47         MockHandlerImpl<?> handler = new MockHandlerImpl(new MockSettingsImpl());
48         mockingProgress().verificationStarted(VerificationModeFactory.atLeastOnce());
49         handler.matchersBinder = new MatchersBinder() {
50             public InvocationMatcher bindMatchers(ArgumentMatcherStorage argumentMatcherStorage, Invocation invocation) {
51                 throw new InvalidUseOfMatchersException();
52             }
53         };
54 
55         try {
56             // when
57             handler.handle(invocation);
58 
59             // then
60             fail();
61         } catch (InvalidUseOfMatchersException ignored) {
62         }
63 
64         assertNull(mockingProgress().pullVerificationMode());
65     }
66 
67 
68     @Test(expected = MockitoException.class)
should_throw_mockito_exception_when_invocation_handler_throws_anything()69     public void should_throw_mockito_exception_when_invocation_handler_throws_anything() throws Throwable {
70         // given
71         InvocationListener throwingListener = mock(InvocationListener.class);
72         doThrow(new Throwable()).when(throwingListener).reportInvocation(any(MethodInvocationReport.class));
73         MockHandlerImpl<?> handler = create_correctly_stubbed_handler(throwingListener);
74 
75         // when
76         handler.handle(invocation);
77     }
78 
79     @Test(expected = WrongTypeOfReturnValue.class)
should_report_bogus_default_answer()80     public void should_report_bogus_default_answer() throws Throwable {
81         MockSettingsImpl mockSettings = mock(MockSettingsImpl.class);
82         MockHandlerImpl<?> handler = new MockHandlerImpl(mockSettings);
83         given(mockSettings.getDefaultAnswer()).willReturn(new Returns(AWrongType.WRONG_TYPE));
84 
85         @SuppressWarnings("unused") // otherwise cast is not done
86         String there_should_not_be_a_CCE_here = (String) handler.handle(
87                 new InvocationBuilder().method(Object.class.getDeclaredMethod("toString")).toInvocation()
88         );
89     }
90 
create_correctly_stubbed_handler(InvocationListener throwingListener)91     private MockHandlerImpl<?> create_correctly_stubbed_handler(InvocationListener throwingListener) {
92         MockHandlerImpl<?> handler = create_handler_with_listeners(throwingListener);
93         stub_ordinary_invocation_with_given_return_value(handler);
94         return handler;
95     }
96 
stub_ordinary_invocation_with_given_return_value(MockHandlerImpl<?> handler)97     private void stub_ordinary_invocation_with_given_return_value(MockHandlerImpl<?> handler) {
98         stub_ordinary_invocation_with_invocation_matcher(handler, stubbedInvocationMatcher);
99     }
100 
101 
stub_ordinary_invocation_with_invocation_matcher(MockHandlerImpl<?> handler, StubbedInvocationMatcher value)102     private void stub_ordinary_invocation_with_invocation_matcher(MockHandlerImpl<?> handler, StubbedInvocationMatcher value) {
103         handler.invocationContainer = mock(InvocationContainerImpl.class);
104         given(handler.invocationContainer.findAnswerFor(any(Invocation.class))).willReturn(value);
105     }
106 
107 
create_handler_with_listeners(InvocationListener... listener)108     private MockHandlerImpl<?> create_handler_with_listeners(InvocationListener... listener) {
109         @SuppressWarnings("rawtypes")
110         MockHandlerImpl<?> handler = new MockHandlerImpl(mock(MockSettingsImpl.class));
111         handler.matchersBinder = mock(MatchersBinder.class);
112         given(handler.getMockSettings().getInvocationListeners()).willReturn(Arrays.asList(listener));
113         return handler;
114     }
115 
116     private static class AWrongType {
117         public static final AWrongType WRONG_TYPE = new AWrongType();
118     }
119 }
120