• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2016 Mockito contributors
3  * This program is made available under the terms of the MIT License.
4  */
5 package org.mockito.internal.creation.bytebuddy;
6 
7 import net.bytebuddy.implementation.bind.annotation.AllArguments;
8 import net.bytebuddy.implementation.bind.annotation.Argument;
9 import net.bytebuddy.implementation.bind.annotation.BindingPriority;
10 import net.bytebuddy.implementation.bind.annotation.FieldValue;
11 import net.bytebuddy.implementation.bind.annotation.Origin;
12 import net.bytebuddy.implementation.bind.annotation.RuntimeType;
13 import net.bytebuddy.implementation.bind.annotation.StubValue;
14 import net.bytebuddy.implementation.bind.annotation.SuperCall;
15 import net.bytebuddy.implementation.bind.annotation.This;
16 import org.mockito.internal.debugging.LocationImpl;
17 import org.mockito.internal.invocation.RealMethod;
18 import org.mockito.invocation.Location;
19 import org.mockito.invocation.MockHandler;
20 import org.mockito.mock.MockCreationSettings;
21 
22 import java.io.ObjectStreamException;
23 import java.io.Serializable;
24 import java.lang.reflect.Method;
25 import java.util.concurrent.Callable;
26 
27 import static org.mockito.internal.invocation.DefaultInvocationFactory.createInvocation;
28 
29 public class MockMethodInterceptor implements Serializable {
30 
31     private static final long serialVersionUID = 7152947254057253027L;
32 
33     final MockHandler handler;
34 
35     private final MockCreationSettings mockCreationSettings;
36 
37     private final ByteBuddyCrossClassLoaderSerializationSupport serializationSupport;
38 
MockMethodInterceptor(MockHandler handler, MockCreationSettings mockCreationSettings)39     public MockMethodInterceptor(MockHandler handler, MockCreationSettings mockCreationSettings) {
40         this.handler = handler;
41         this.mockCreationSettings = mockCreationSettings;
42         serializationSupport = new ByteBuddyCrossClassLoaderSerializationSupport();
43     }
44 
doIntercept(Object mock, Method invokedMethod, Object[] arguments, RealMethod realMethod)45     Object doIntercept(Object mock,
46                        Method invokedMethod,
47                        Object[] arguments,
48                        RealMethod realMethod) throws Throwable {
49         return doIntercept(
50                 mock,
51                 invokedMethod,
52                 arguments,
53             realMethod,
54                 new LocationImpl()
55         );
56     }
57 
doIntercept(Object mock, Method invokedMethod, Object[] arguments, RealMethod realMethod, Location location)58     Object doIntercept(Object mock,
59                        Method invokedMethod,
60                        Object[] arguments,
61                        RealMethod realMethod,
62                        Location location) throws Throwable {
63         return handler.handle(createInvocation(mock, invokedMethod, arguments, realMethod, mockCreationSettings, location));
64     }
65 
getMockHandler()66     public MockHandler getMockHandler() {
67         return handler;
68     }
69 
getSerializationSupport()70     public ByteBuddyCrossClassLoaderSerializationSupport getSerializationSupport() {
71         return serializationSupport;
72     }
73 
74     public static class ForHashCode {
75 
76         @SuppressWarnings("unused")
doIdentityHashCode(@his Object thiz)77         public static int doIdentityHashCode(@This Object thiz) {
78             return System.identityHashCode(thiz);
79         }
80     }
81 
82     public static class ForEquals {
83 
84         @SuppressWarnings("unused")
doIdentityEquals(@his Object thiz, @Argument(0) Object other)85         public static boolean doIdentityEquals(@This Object thiz, @Argument(0) Object other) {
86             return thiz == other;
87         }
88     }
89 
90     public static class ForWriteReplace {
91 
doWriteReplace(@his MockAccess thiz)92         public static Object doWriteReplace(@This MockAccess thiz) throws ObjectStreamException {
93             return thiz.getMockitoInterceptor().getSerializationSupport().writeReplace(thiz);
94         }
95     }
96 
97     public static class DispatcherDefaultingToRealMethod {
98 
99         @SuppressWarnings("unused")
100         @RuntimeType
101         @BindingPriority(BindingPriority.DEFAULT * 2)
interceptSuperCallable(@his Object mock, @FieldValue("mockitoInterceptor") MockMethodInterceptor interceptor, @Origin Method invokedMethod, @AllArguments Object[] arguments, @SuperCall(serializableProxy = true) Callable<?> superCall)102         public static Object interceptSuperCallable(@This Object mock,
103                                                     @FieldValue("mockitoInterceptor") MockMethodInterceptor interceptor,
104                                                     @Origin Method invokedMethod,
105                                                     @AllArguments Object[] arguments,
106                                                     @SuperCall(serializableProxy = true) Callable<?> superCall) throws Throwable {
107             if (interceptor == null) {
108                 return superCall.call();
109             }
110             return interceptor.doIntercept(
111                     mock,
112                     invokedMethod,
113                     arguments,
114                     new RealMethod.FromCallable(superCall)
115             );
116         }
117 
118         @SuppressWarnings("unused")
119         @RuntimeType
interceptAbstract(@his Object mock, @FieldValue("mockitoInterceptor") MockMethodInterceptor interceptor, @StubValue Object stubValue, @Origin Method invokedMethod, @AllArguments Object[] arguments)120         public static Object interceptAbstract(@This Object mock,
121                                                @FieldValue("mockitoInterceptor") MockMethodInterceptor interceptor,
122                                                @StubValue Object stubValue,
123                                                @Origin Method invokedMethod,
124                                                @AllArguments Object[] arguments) throws Throwable {
125             if (interceptor == null) {
126                 return stubValue;
127             }
128             return interceptor.doIntercept(
129                     mock,
130                     invokedMethod,
131                     arguments,
132                     RealMethod.IsIllegal.INSTANCE
133             );
134         }
135     }
136 }
137