How to use method of org.mockito.internal.creation.bytebuddy.BytecodeGenerator class

Best Mockito code snippet using org.mockito.internal.creation.bytebuddy.BytecodeGenerator.

Run Mockito automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

copy
1/*
2 * Copyright (c) 2016 Mockito contributors
3 * This program is made available under the terms of the MIT License.
4 */
5package org.mockito.internal.creation.bytebuddy;
6
7import static java.lang.Thread.currentThread;
8
9import static net.bytebuddy.description.modifier.Visibility.PRIVATE;
10import static net.bytebuddy.dynamic.Transformer.ForMethod.withModifiers;
11import static net.bytebuddy.implementation.MethodDelegation.to;
12import static net.bytebuddy.implementation.attribute.MethodAttributeAppender.ForInstrumentedMethod.INCLUDING_RECEIVER;
13import static net.bytebuddy.matcher.ElementMatchers.*;
14import static org.mockito.internal.util.StringUtil.join;
15
16import java.io.IOException;
17import java.io.ObjectInputStream;
18import java.lang.annotation.Annotation;
19import java.lang.reflect.Modifier;
20import java.lang.reflect.Type;
21import java.util.ArrayList;
22import java.util.Collection;
23import java.util.Iterator;
24import java.util.LinkedList;
25import java.util.Random;
26
27import net.bytebuddy.ByteBuddy;
28import net.bytebuddy.description.method.MethodDescription;
29import net.bytebuddy.description.modifier.SynchronizationState;
30import net.bytebuddy.description.modifier.Visibility;
31import net.bytebuddy.dynamic.DynamicType;
32import net.bytebuddy.dynamic.loading.MultipleParentClassLoader;
33import net.bytebuddy.dynamic.scaffold.TypeValidation;
34import net.bytebuddy.implementation.FieldAccessor;
35import net.bytebuddy.implementation.Implementation;
36import net.bytebuddy.implementation.attribute.MethodAttributeAppender;
37import net.bytebuddy.matcher.ElementMatcher;
38import org.mockito.codegen.InjectionBase;
39import org.mockito.exceptions.base.MockitoException;
40import org.mockito.internal.creation.bytebuddy.ByteBuddyCrossClassLoaderSerializationSupport.CrossClassLoaderSerializableMock;
41import org.mockito.internal.creation.bytebuddy.MockMethodInterceptor.DispatcherDefaultingToRealMethod;
42import org.mockito.mock.SerializableMode;
43
44class SubclassBytecodeGenerator implements BytecodeGenerator {
45
46    private static final String CODEGEN_PACKAGE = "org.mockito.codegen.";
47
48    private final SubclassLoader loader;
49    private final ModuleHandler handler;
50    private final ByteBuddy byteBuddy;
51    private final Random random;
52    private final Implementation readReplace;
53    private final ElementMatcher<? super MethodDescription> matcher;
54
55    private final Implementation dispatcher = to(DispatcherDefaultingToRealMethod.class);
56    private final Implementation hashCode = to(MockMethodInterceptor.ForHashCode.class);
57    private final Implementation equals = to(MockMethodInterceptor.ForEquals.class);
58    private final Implementation writeReplace = to(MockMethodInterceptor.ForWriteReplace.class);
59
60    public SubclassBytecodeGenerator() {
61        this(new SubclassInjectionLoader());
62    }
63
64    public SubclassBytecodeGenerator(SubclassLoader loader) {
65        this(loader, null, any());
66    }
67
68    public SubclassBytecodeGenerator(
69            Implementation readReplace, ElementMatcher<? super MethodDescription> matcher) {
70        this(new SubclassInjectionLoader(), readReplace, matcher);
71    }
72
73    protected SubclassBytecodeGenerator(
74            SubclassLoader loader,
75            Implementation readReplace,
76            ElementMatcher<? super MethodDescription> matcher) {
77        this.loader = loader;
78        this.readReplace = readReplace;
79        this.matcher = matcher;
80        byteBuddy = new ByteBuddy().with(TypeValidation.DISABLED);
81        random = new Random();
82        handler = ModuleHandler.make(byteBuddy, loader, random);
83    }
84
85    @Override
86    public <T> Class<? extends T> mockClass(MockFeatures<T> features) {
87        ClassLoader classLoader =
88                new MultipleParentClassLoader.Builder()
89                        .appendMostSpecific(getAllTypes(features.mockedType))
90                        .appendMostSpecific(features.interfaces)
91                        .appendMostSpecific(currentThread().getContextClassLoader())
92                        .appendMostSpecific(MockAccess.class)
93                        .build();
94
95        // If Mockito does not need to create a new class loader and if a mock is not based on a JDK
96        // type, we attempt
97        // to define the mock class in the user runtime package to allow for mocking package private
98        // types and methods.
99        // This also requires that we are able to access the package of the mocked class either by
100        // override or explicit
101        // privilege given by the target package being opened to Mockito.
102        boolean localMock =
103                classLoader == features.mockedType.getClassLoader()
104                        && features.serializableMode != SerializableMode.ACROSS_CLASSLOADERS
105                        && !isComingFromJDK(features.mockedType)
106                        && (loader.isDisrespectingOpenness()
107                                || handler.isOpened(features.mockedType, MockAccess.class));
108        String typeName;
109        if (localMock
110                || loader instanceof MultipleParentClassLoader
111                        && !isComingFromJDK(features.mockedType)) {
112            typeName = features.mockedType.getName();
113        } else {
114            typeName =
115                    InjectionBase.class.getPackage().getName()
116                            + "."
117                            + features.mockedType.getSimpleName();
118        }
119        String name =
120                String.format("%s$%s$%d", typeName, "MockitoMock", Math.abs(random.nextInt()));
121
122        if (localMock) {
123            handler.adjustModuleGraph(features.mockedType, MockAccess.class, false, true);
124            for (Class<?> iFace : features.interfaces) {
125                handler.adjustModuleGraph(iFace, features.mockedType, true, false);
126                handler.adjustModuleGraph(features.mockedType, iFace, false, true);
127            }
128        } else {
129            boolean exported = handler.isExported(features.mockedType);
130            Iterator<Class<?>> it = features.interfaces.iterator();
131            while (exported && it.hasNext()) {
132                exported = handler.isExported(it.next());
133            }
134            // We check if all mocked types are exported without qualification to avoid generating a
135            // hook type.
136            // unless this is necessary. We expect this to be the case for most mocked types what
137            // makes this a
138            // worthy performance optimization.
139            if (exported) {
140                assertVisibility(features.mockedType);
141                for (Class<?> iFace : features.interfaces) {
142                    assertVisibility(iFace);
143                }
144            } else {
145                Class<?> hook = handler.injectionBase(classLoader, typeName);
146                assertVisibility(features.mockedType);
147                handler.adjustModuleGraph(features.mockedType, hook, true, false);
148                for (Class<?> iFace : features.interfaces) {
149                    assertVisibility(iFace);
150                    handler.adjustModuleGraph(iFace, hook, true, false);
151                }
152            }
153        }
154
155        DynamicType.Builder<T> builder =
156                byteBuddy
157                        .subclass(features.mockedType)
158                        .name(name)
159                        .ignoreAlso(isGroovyMethod())
160                        .annotateType(
161                                features.stripAnnotations
162                                        ? new Annotation[0]
163                                        : features.mockedType.getAnnotations())
164                        .implement(new ArrayList<Type>(features.interfaces))
165                        .method(matcher)
166                        .intercept(dispatcher)
167                        .transform(withModifiers(SynchronizationState.PLAIN))
168                        .attribute(
169                                features.stripAnnotations
170                                        ? MethodAttributeAppender.NoOp.INSTANCE
171                                        : INCLUDING_RECEIVER)
172                        .method(isHashCode())
173                        .intercept(hashCode)
174                        .method(isEquals())
175                        .intercept(equals)
176                        .serialVersionUid(42L)
177                        .defineField("mockitoInterceptor", MockMethodInterceptor.class, PRIVATE)
178                        .implement(MockAccess.class)
179                        .intercept(FieldAccessor.ofBeanProperty());
180        if (features.serializableMode == SerializableMode.ACROSS_CLASSLOADERS) {
181            builder =
182                    builder.implement(CrossClassLoaderSerializableMock.class)
183                            .intercept(writeReplace);
184        }
185        if (readReplace != null) {
186            builder =
187                    builder.defineMethod("readObject", void.class, Visibility.PRIVATE)
188                            .withParameters(ObjectInputStream.class)
189                            .throwing(ClassNotFoundException.class, IOException.class)
190                            .intercept(readReplace);
191        }
192        if (name.startsWith(CODEGEN_PACKAGE) || classLoader instanceof MultipleParentClassLoader) {
193            builder =
194                    builder.ignoreAlso(
195                            isPackagePrivate()
196                                    .or(returns(isPackagePrivate()))
197                                    .or(hasParameters(whereAny(hasType(isPackagePrivate())))));
198        }
199        return builder.make()
200                .load(
201                        classLoader,
202                        loader.resolveStrategy(features.mockedType, classLoader, localMock))
203                .getLoaded();
204    }
205
206    @Override
207    public void mockClassStatic(Class<?> type) {
208        throw new MockitoException("The subclass byte code generator cannot create static mocks");
209    }
210
211    @Override
212    public void mockClassConstruction(Class<?> type) {
213        throw new MockitoException(
214                "The subclass byte code generator cannot create construction mocks");
215    }
216
217    private <T> Collection<Class<? super T>> getAllTypes(Class<T> type) {
218        Collection<Class<? super T>> supertypes = new LinkedList<Class<? super T>>();
219        supertypes.add(type);
220        Class<? super T> superType = type;
221        while (superType != null) {
222            supertypes.add(superType);
223            superType = superType.getSuperclass();
224        }
225        return supertypes;
226    }
227
228    private static ElementMatcher<MethodDescription> isGroovyMethod() {
229        return isDeclaredBy(named("groovy.lang.GroovyObjectSupport"));
230    }
231
232    private boolean isComingFromJDK(Class<?> type) {
233        // Comes from the manifest entry :
234        // Implementation-Title: Java Runtime Environment
235        // This entry is not necessarily present in every jar of the JDK
236        return type.getPackage() != null
237                        && "Java Runtime Environment"
238                                .equalsIgnoreCase(type.getPackage().getImplementationTitle())
239                || type.getName().startsWith("java.")
240                || type.getName().startsWith("javax.");
241    }
242
243    private static void assertVisibility(Class<?> type) {
244        if (!Modifier.isPublic(type.getModifiers())) {
245            throw new MockitoException(
246                    join(
247                            "Cannot create mock for " + type,
248                            "",
249                            "The type is not public and its mock class is loaded by a different class loader.",
250                            "This can have multiple reasons:",
251                            " - You are mocking a class with additional interfaces of another class loader",
252                            " - Mockito is loaded by a different class loader than the mocked type (e.g. with OSGi)",
253                            " - The thread's context class loader is different than the mock's class loader"));
254        }
255    }
256}
257
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest

Trigger code on LambdaTest Cloud Grid

Execute automation tests with on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.

Test now for Free
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)