How to use method of org.jmock.imposters.ByteBuddyClassImposteriser class

Best Jmock-library code snippet using org.jmock.imposters.ByteBuddyClassImposteriser.

Run Jmock-library automation tests on LambdaTest cloud grid

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

copy
1/*
2 * Copyright (c) 2016-2021 Deephaven Data Labs and Patent Pending
3 */
4
5package io.deephaven.base.testing;
6
7import io.deephaven.base.Function;
8import io.deephaven.base.verify.Assert;
9import junit.framework.TestCase;
10import org.hamcrest.CoreMatchers;
11import org.hamcrest.Matcher;
12import org.jmock.Mockery;
13import org.jmock.Sequence;
14import org.jmock.States;
15import org.jmock.api.Imposteriser;
16import org.jmock.api.Invocation;
17import org.jmock.api.Invokable;
18import org.jmock.auto.internal.Mockomatic;
19import org.jmock.imposters.ByteBuddyClassImposteriser;
20import org.jmock.internal.ExpectationBuilder;
21import org.jmock.lib.action.CustomAction;
22import org.jmock.lib.concurrent.Synchroniser;
23
24import java.lang.reflect.*;
25import java.util.Arrays;
26import java.util.HashMap;
27import java.util.Map;
28import java.util.concurrent.atomic.AtomicInteger;
29
30abstract public class BaseCachedJMockTestCase extends TestCase {
31    protected final Mockery context;
32
33    {
34        // use an initializer rather than setUp so forgetting to
35        // call super.setUp won't use the wrong imposteriser
36        context = new Mockery();
37        context.setThreadingPolicy(new Synchroniser());
38        context.setImposteriser(CachingImposteriser.INSTANCE);
39        new Mockomatic(context).fillIn(this);
40    }
41
42
43    public <T> T mock(Class<T> tClass) {
44        return context.mock(tClass);
45    }
46
47    public <T> T mock(Class<T> tClass, String s) {
48        return context.mock(tClass, s);
49    }
50
51    public States states(String s) {
52        return context.states(s);
53    }
54
55    public Sequence sequence(String s) {
56        return context.sequence(s);
57    }
58
59    public void checking(ExpectationBuilder expectationBuilder) {
60        context.checking(expectationBuilder);
61    }
62
63    public void assertIsSatisfied() {
64        context.assertIsSatisfied();
65    }
66
67    @Override
68    protected void tearDown() throws Exception {
69        context.assertIsSatisfied();
70        super.tearDown();
71    }
72
73    public static class Expectations extends org.jmock.Expectations {
74
75        public static <T> Matcher<T> some(Class<T> type) {
76            return CoreMatchers.instanceOf(type);
77        }
78
79        public static <T> Matcher<T> any(Class<T> type) {
80            return CoreMatchers.anyOf(CoreMatchers.instanceOf(type), CoreMatchers.nullValue(type));
81        }
82
83        private static AtomicInteger willDoCounter = new AtomicInteger(0);
84
85        public void willDo(final Function.Nullary<Object> proc) {
86            this.currentBuilder().setAction(run(proc));
87        }
88
89        public static CustomAction run(final Function.Nullary<Object> proc) {
90            return new CustomAction("willDo_" + willDoCounter.incrementAndGet()) {
91                @Override
92                public Object invoke(Invocation invocation) throws Throwable {
93                    return proc.call();
94                }
95            };
96        }
97
98        public void willDo(final Function.Unary<Object, Invocation> proc) {
99            this.currentBuilder().setAction(run(proc));
100        }
101
102        public static CustomAction run(final Function.Unary<Object, Invocation> proc) {
103            return new CustomAction("willDo_" + willDoCounter.incrementAndGet()) {
104                @Override
105                public Object invoke(Invocation invocation) throws Throwable {
106                    return proc.call(invocation);
107                }
108            };
109        }
110    }
111
112    // ----------------------------------------------------------------
113    public static class CachingImposteriser implements Imposteriser {
114
115        public static final BaseCachedJMockTestCase.CachingImposteriser INSTANCE = new CachingImposteriser();
116
117        private final static Class[] CONSTRUCTOR_PARAMS = {InvocationHandler.class};
118
119        private static Map<ProxyInfo, Function.Unary<?, Invokable>> proxyInfoToConstructorMap = new HashMap<>();
120
121        // ----------------------------------------------------------------
122        @Override // from Imposteriser
123        public boolean canImposterise(Class<?> type) {
124            return ByteBuddyClassImposteriser.INSTANCE.canImposterise(type);
125        }
126
127        // ----------------------------------------------------------------
128        @Override // from Imposteriser
129        public <T> T imposterise(final Invokable mockObject, Class<T> mockedType, Class<?>... ancillaryTypes) {
130            ProxyInfo proxyInfo = new ProxyInfo(mockedType, ancillaryTypes);
131            Function.Unary<?, Invokable> constructor = proxyInfoToConstructorMap.get(proxyInfo);
132            if (null == constructor) {
133                constructor = createConstructor(proxyInfo);
134                proxyInfoToConstructorMap.put(proxyInfo, constructor);
135            }
136            // noinspection unchecked
137            return (T) constructor.call(mockObject);
138        }
139
140        // ----------------------------------------------------------------
141        private Function.Unary<?, Invokable> createConstructor(ProxyInfo proxyInfo) {
142            if (proxyInfo.mockedType.isInterface()) {
143                return createInterfaceConstructor(proxyInfo);
144            } else {
145                return createClassConstructor(proxyInfo);
146            }
147        }
148
149        // ----------------------------------------------------------------
150        /** Based on {@link org.jmock.lib.JavaReflectionImposteriser}. */
151        private Function.Unary<?, Invokable> createInterfaceConstructor(ProxyInfo proxyInfo) {
152            ClassLoader proxyClassLoader = BaseCachedJMockTestCase.class.getClassLoader();
153            Class proxyClass = Proxy.getProxyClass(proxyClassLoader, proxyInfo.proxiedClasses);
154
155            final Constructor constructor;
156            try {
157                constructor = proxyClass.getConstructor(CONSTRUCTOR_PARAMS);
158            } catch (NoSuchMethodException e) {
159                throw Assert.exceptionNeverCaught(e);
160            }
161            return new Function.Unary<Object, Invokable>() {
162                @Override
163                public Object call(final Invokable invokable) {
164                    try {
165                        return constructor.newInstance(new InvocationHandler() {
166                            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
167                                return invokable.invoke(new Invocation(proxy, method, args));
168                            }
169                        });
170                    } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
171                        throw Assert.exceptionNeverCaught(e);
172                    }
173                }
174            };
175        }
176
177        // ----------------------------------------------------------------
178        /** Based on {@link ByteBuddyClassImposteriser}. */
179        private Function.Unary<?, Invokable> createClassConstructor(final ProxyInfo proxyInfo) {
180            return imposter -> ByteBuddyClassImposteriser.INSTANCE.imposterise(imposter, proxyInfo.mockedType,
181                    proxyInfo.ancillaryTypes);
182        }
183    }
184
185    // ----------------------------------------------------------------
186    private static class ProxyInfo {
187
188        public Class[] proxiedClasses;
189        public Class mockedType;
190        public Class[] ancillaryTypes;
191
192
193        // ----------------------------------------------------------------
194        public ProxyInfo(Class<?> mockedType, Class<?>... ancillaryTypes) {
195            this.mockedType = mockedType;
196            this.ancillaryTypes = ancillaryTypes;
197            proxiedClasses = new Class<?>[ancillaryTypes.length + 1];
198            proxiedClasses[0] = mockedType;
199            System.arraycopy(ancillaryTypes, 0, proxiedClasses, 1, ancillaryTypes.length);
200        }
201
202        // ------------------------------------------------------------
203        @Override
204        public boolean equals(Object that) {
205            if (this == that) {
206                return true;
207            }
208            if (that == null || getClass() != that.getClass()) {
209                return false;
210            }
211            ProxyInfo proxyInfo = (ProxyInfo) that;
212            if (!Arrays.equals(proxiedClasses, proxyInfo.proxiedClasses)) {
213                return false;
214            }
215            return true;
216        }
217
218        // ------------------------------------------------------------
219        @Override
220        public int hashCode() {
221            return Arrays.hashCode(proxiedClasses);
222        }
223
224        // ------------------------------------------------------------
225        @Override
226        public String toString() {
227            StringBuilder stringBuilder = new StringBuilder();
228            for (Class proxiedClass : proxiedClasses) {
229                stringBuilder.append(0 == stringBuilder.length() ? "[" : ", ").append(proxiedClass.getSimpleName());
230            }
231            return stringBuilder.append("]").toString();
232        }
233    }
234}
235
Full Screen
copy
1package org.jmock.imposters;
2
3import java.lang.reflect.Constructor;
4import java.lang.reflect.InvocationTargetException;
5import java.lang.reflect.Method;
6import java.lang.reflect.Modifier;
7import java.util.HashSet;
8import java.util.Map;
9import java.util.Set;
10import java.util.concurrent.ConcurrentHashMap;
11import java.util.function.Function;
12
13import net.bytebuddy.dynamic.scaffold.TypeValidation;
14import org.jmock.api.Imposteriser;
15import org.jmock.api.Invocation;
16import org.jmock.api.Invokable;
17import org.jmock.internal.SearchingClassLoader;
18import org.objenesis.Objenesis;
19import org.objenesis.ObjenesisStd;
20
21import net.bytebuddy.ByteBuddy;
22import net.bytebuddy.NamingStrategy;
23import net.bytebuddy.description.modifier.Visibility;
24import net.bytebuddy.dynamic.DynamicType.Builder;
25import net.bytebuddy.dynamic.loading.ClassInjector;
26import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
27import net.bytebuddy.implementation.FieldAccessor;
28import net.bytebuddy.implementation.MethodDelegation;
29import net.bytebuddy.implementation.bind.annotation.AllArguments;
30import net.bytebuddy.implementation.bind.annotation.FieldValue;
31import net.bytebuddy.implementation.bind.annotation.Origin;
32import net.bytebuddy.implementation.bind.annotation.RuntimeType;
33import net.bytebuddy.implementation.bind.annotation.This;
34import net.bytebuddy.matcher.ElementMatchers;
35
36/**
37 * This class lets you imposterise abstract and concrete classes
38 * <em>without</em> calling the constructors of the mocked class.
39 * 
40 * @author olibye
41 */
42public class ByteBuddyClassImposteriser implements Imposteriser {
43
44    public static final Imposteriser INSTANCE = new ByteBuddyClassImposteriser();
45    private static final String JMOCK_KEY = "jMock";
46
47    private final Objenesis objenesis = new ObjenesisStd();
48    private final Map<Set<Class<?>>, Class<?>> types = new ConcurrentHashMap<Set<Class<?>>, Class<?>>();
49
50    private ByteBuddyClassImposteriser() {
51    }
52
53    public boolean canImposterise(Class<?> type) {
54        return !type.isPrimitive() &&
55                !Modifier.isFinal(type.getModifiers()) &&
56                (type.isInterface() || !toStringMethodIsFinal(type));
57    }
58
59    @Override
60    public <T> T imposterise(final Invokable mockObject, Class<T> mockedType, Class<?>... ancilliaryTypes) {
61        if (!mockedType.isInterface() && toStringMethodIsFinal(mockedType)) {
62            throw new IllegalArgumentException(mockedType.getName() + " has a final toString method");
63        }
64
65        try {
66            setConstructorsAccessible(mockedType, true);
67            return proxy(mockObject, mockedType, ancilliaryTypes);
68        } finally {
69            setConstructorsAccessible(mockedType, false);
70        }
71    }
72
73    private boolean toStringMethodIsFinal(Class<?> type) {
74        try {
75            Method toString = type.getMethod("toString");
76            return Modifier.isFinal(toString.getModifiers());
77
78        } catch (SecurityException e) {
79            throw new IllegalStateException("not allowed to reflect on toString method", e);
80        } catch (NoSuchMethodException e) {
81            throw new Error("no public toString method found", e);
82        }
83    }
84
85    private void setConstructorsAccessible(Class<?> mockedType, boolean accessible) {
86        for (Constructor<?> constructor : mockedType.getDeclaredConstructors()) {
87            constructor.setAccessible(accessible);
88        }
89    }
90
91    private <T> T proxy(
92            final Invokable mockObject, final Class<T> mockedType, final Class<?>... ancilliaryTypes) {
93
94        try {
95            Set<Class<?>> mockTypeKey = mockTypeKey(mockedType, ancilliaryTypes);
96            Class<?> proxyType = types.computeIfAbsent(mockTypeKey,
97                    new Function<Object, Class<?>>() {
98                        @Override
99                        public Class<?> apply(Object t) {
100                            try {
101                                return proxyClass(mockObject, mockedType, ancilliaryTypes);
102                            } catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException
103                                    | NoSuchMethodException e) {
104                                throw new RuntimeException(e);
105                            }
106                        }
107                    });
108
109            InjectInvokable invokable = (InjectInvokable) objenesis.newInstance(proxyType);
110            invokable.setJMock(mockObject);
111            return (T) invokable;
112
113        } catch (IllegalArgumentException | SecurityException e) {
114            throw new RuntimeException("Exception in code generation strategy available", e);
115        }
116    }
117
118    public interface InjectInvokable {
119        void setJMock(Invokable invokable);
120        Invokable getJMock();
121    }
122    
123    public static class Interceptor {
124        @RuntimeType
125        static public Object intercept(
126                @This Object receiver,
127                @Origin Method method,
128                @FieldValue(value=JMOCK_KEY) Invokable invokable,
129                @AllArguments Object[] args
130                ) throws Throwable {
131            return invokable.invoke(new Invocation(receiver, method, args));
132        }
133    }
134
135    private Class<?> proxyClass(final Invokable mockObject, final Class<?> mockedType, Class<?>... ancilliaryTypes)
136            throws ClassNotFoundException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
137        Builder<?> builder = new ByteBuddy()
138                .with(TypeValidation.DISABLED)
139                .with(new NamingStrategy.SuffixingRandom(JMOCK_KEY, JMOCK_KEY.toLowerCase()))
140                .subclass(mockedType)
141                .implement(ancilliaryTypes)
142                .defineField(JMOCK_KEY, Invokable.class, Visibility.PRIVATE)
143                .implement(InjectInvokable.class).intercept(FieldAccessor.ofField(JMOCK_KEY))
144                .method(ElementMatchers.not(ElementMatchers.isDeclaredBy(InjectInvokable.class)))
145                .intercept(MethodDelegation.to(Interceptor.class));
146/*                
147                .intercept(InvocationHandlerAdapter.of(new InvocationHandler() {
148                    public Object invoke(Object receiver, Method method, Object[] args) throws Throwable {
149                        return mockObject.invoke(new Invocation(receiver, method, args));
150                    }
151                }));
152*/
153        // From
154        // https://mydailyjava.blogspot.com/2018/04/jdk-11-and-proxies-in-world-past.html
155        ClassLoadingStrategy<ClassLoader> strategy;
156        if (ClassInjector.UsingLookup.isAvailable() && !protectedPackageNameSpaces(mockedType)
157                && !defaultPackage(mockedType)
158                && mockedType.getClassLoader() == this.getClass().getClassLoader()) {
159            Class<?> methodHandles = Class.forName("java.lang.invoke.MethodHandles");
160            Object lookup = methodHandles.getMethod("lookup").invoke(null);
161            Method privateLookupIn = methodHandles.getMethod("privateLookupIn",
162                    Class.class,
163                    Class.forName("java.lang.invoke.MethodHandles$Lookup"));
164            Object privateLookup = privateLookupIn.invoke(null, mockedType, lookup);
165            strategy = ClassLoadingStrategy.UsingLookup.of(privateLookup);
166        } else if (ClassInjector.UsingReflection.isAvailable()) {
167            strategy = ClassLoadingStrategy.Default.INJECTION;
168        } else {
169            throw new IllegalStateException("No code generation strategy available");
170        }
171
172        Class<?> proxyType = builder.make()
173                .load(SearchingClassLoader.combineLoadersOf(mockedType, ancilliaryTypes), strategy)
174                .getLoaded();
175        return proxyType;
176    }
177
178    private Set<Class<?>> mockTypeKey(final Class<?> mockedType, Class<?>... ancilliaryTypes) {
179        Set<Class<?>> types = new HashSet<>();
180        types.add(mockedType);
181        for (Class<?> class1 : ancilliaryTypes) {
182            types.add(class1);
183        }
184        return types;
185    }
186
187    private boolean defaultPackage(Class<?> mockedType) {
188        return mockedType.getPackage().getName().isEmpty();
189    }
190
191    private boolean protectedPackageNameSpaces(Class<?> mockedType) {
192        return mockedType.getName().startsWith("java.");
193    }
194}
195
Full Screen
copy
1package org.jmock.lib.legacy;
2
3import net.sf.cglib.core.CodeGenerationException;
4import net.sf.cglib.core.DefaultNamingPolicy;
5import net.sf.cglib.core.NamingPolicy;
6import net.sf.cglib.core.Predicate;
7import net.sf.cglib.proxy.*;
8import org.jmock.api.Imposteriser;
9import org.jmock.api.Invocation;
10import org.jmock.api.Invokable;
11import org.jmock.internal.SearchingClassLoader;
12import org.objenesis.Objenesis;
13import org.objenesis.ObjenesisStd;
14
15import java.lang.reflect.Constructor;
16import java.lang.reflect.Method;
17import java.lang.reflect.Modifier;
18import java.util.List;
19
20/**
21 * This class lets you imposterise abstract and concrete classes 
22 * <em>without</em> calling the constructors of the mocked class.
23 *   
24 * @author npryce
25 * 
26 * @deprecated Java11 support is weak, Migrate to org.jmock.lib.imposters.ByteBuddyClassImposteriser
27 */
28public class ClassImposteriser implements Imposteriser {
29    public static final Imposteriser INSTANCE = new ClassImposteriser();
30    
31    private ClassImposteriser() {}
32
33    private static final Method FINALIZE_METHOD = findFinalizeMethod();
34
35    private static final NamingPolicy NAMING_POLICY_THAT_ALLOWS_IMPOSTERISATION_OF_CLASSES_IN_SIGNED_PACKAGES = new DefaultNamingPolicy() {
36        @Override
37        public String getClassName(String prefix, String source, Object key, Predicate names) {
38            return "org.jmock.codegen." + super.getClassName(prefix, source, key, names);
39        }
40    };
41    
42    private static final CallbackFilter IGNORED_METHODS = new CallbackFilter() {
43        public int accept(Method method) {
44            if (method.isBridge())
45                return 1;
46            else if (method.equals(FINALIZE_METHOD))
47                return 1;
48            else
49                return 0;
50        }
51    };
52    
53    private final Objenesis objenesis = new ObjenesisStd();
54    
55    public boolean canImposterise(Class<?> type) {
56        return !type.isPrimitive() && 
57               !Modifier.isFinal(type.getModifiers()) && 
58               (type.isInterface() || !toStringMethodIsFinal(type));
59    }
60    
61    @Override
62    public <T> T imposterise(final Invokable mockObject, Class<T> mockedType, Class<?>... ancilliaryTypes) {
63        if (!mockedType.isInterface() && toStringMethodIsFinal(mockedType)) {
64            throw new IllegalArgumentException(mockedType.getName() + " has a final toString method");
65        }
66        
67        try {
68            setConstructorsAccessible(mockedType, true);
69            return mockedType.cast(proxy(proxyClass(mockedType, ancilliaryTypes), mockObject));
70        }
71        finally {
72            setConstructorsAccessible(mockedType, false);
73        }
74    }
75    
76    private boolean toStringMethodIsFinal(Class<?> type) {
77        try {
78            Method toString = type.getMethod("toString");
79            return Modifier.isFinal(toString.getModifiers());
80            
81        }
82        catch (SecurityException e) {
83            throw new IllegalStateException("not allowed to reflect on toString method", e);
84        }
85        catch (NoSuchMethodException e) {
86            throw new Error("no public toString method found", e);
87        }
88    }
89
90    private void setConstructorsAccessible(Class<?> mockedType, boolean accessible) {
91        for (Constructor<?> constructor : mockedType.getDeclaredConstructors()) {
92            constructor.setAccessible(accessible);
93        }
94    }
95    
96    private Class<?> proxyClass(Class<?> possibleMockedType, Class<?>... ancilliaryTypes) {
97        final Class<?> mockedType =
98            possibleMockedType == Object.class ? ClassWithSuperclassToWorkAroundCglibBug.class : possibleMockedType;
99        
100        final Enhancer enhancer = new Enhancer() {
101            @Override
102            @SuppressWarnings("unchecked")
103            protected void filterConstructors(Class sc, List constructors) {
104                // Don't filter
105            }
106        };
107        enhancer.setClassLoader(SearchingClassLoader.combineLoadersOf(mockedType, ancilliaryTypes));
108        enhancer.setUseFactory(true);
109        if (mockedType.isInterface()) {
110            enhancer.setSuperclass(Object.class);
111            enhancer.setInterfaces(prepend(mockedType, ancilliaryTypes));
112        }
113        else {
114            enhancer.setSuperclass(mockedType);
115            enhancer.setInterfaces(ancilliaryTypes);
116        }
117        enhancer.setCallbackTypes(new Class[]{InvocationHandler.class, NoOp.class});
118        enhancer.setCallbackFilter(IGNORED_METHODS);
119        if (protectedPackageNamespace(mockedType)) {
120            enhancer.setNamingPolicy(NAMING_POLICY_THAT_ALLOWS_IMPOSTERISATION_OF_CLASSES_IN_SIGNED_PACKAGES);
121        }
122        
123        try {
124            return enhancer.createClass();
125        }
126        catch (CodeGenerationException e) {
127            // Note: I've only been able to manually test this.  It exists to help people writing
128            //       Eclipse plug-ins or using other environments that have sophisticated class loader
129            //       structures.
130            throw new IllegalArgumentException("could not imposterise " + mockedType, e);
131        }
132    }
133    
134    private Object proxy(Class<?> proxyClass, final Invokable mockObject) {
135        final Factory proxy = (Factory)objenesis.newInstance(proxyClass);
136        proxy.setCallbacks(new Callback[] {
137            new InvocationHandler() {
138                public Object invoke(Object receiver, Method method, Object[] args) throws Throwable {
139                    return mockObject.invoke(new Invocation(receiver, method, args));
140                }
141            },
142            NoOp.INSTANCE
143        });
144        return proxy;
145    }
146    
147    private Class<?>[] prepend(Class<?> first, Class<?>... rest) {
148        Class<?>[] all = new Class<?>[rest.length+1];
149        all[0] = first;
150        System.arraycopy(rest, 0, all, 1, rest.length);
151        return all;
152    }
153
154    private static Method findFinalizeMethod() {
155        try {
156            return Object.class.getDeclaredMethod("finalize");
157        } catch (NoSuchMethodException e) {
158            throw new IllegalStateException("Could not find finalize method on Object");
159        }
160    }
161    
162    private boolean protectedPackageNamespace(Class<?> mockedType) {
163        return mockedType.getSigners() != null || mockedType.getName().startsWith("java.");
164    }
165
166    
167    public static class ClassWithSuperclassToWorkAroundCglibBug {}
168}
169
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)