private static void reregisterNativeMethodsForRestoredClass(@Nonnull Class<?> realClass) { Method registerNatives = null; try { registerNatives = realClass.getDeclaredMethod("registerNatives"); } catch (NoSuchMethodException ignore) { try { registerNatives = realClass.getDeclaredMethod("initIDs"); } catch (NoSuchMethodException ignored) { } // OK } if (registerNatives != null) { try { registerNatives.setAccessible(true); registerNatives.invoke(null); } catch (IllegalAccessException ignore) { } // won't happen catch (InvocationTargetException ignore) { } // shouldn't happen either } // OK, although another solution will be required for this particular class if it requires // natives to be explicitly registered again (not all do, such as java.lang.Float). }
@Nullable public InstanceFactory findInstanceFactory(@Nonnull Type mockedType) { InstanceFactory instanceFactory = mockedTypesAndInstances.get(mockedType); if (instanceFactory != null) { return instanceFactory; } Class<?> mockedClass = getClassType(mockedType); //noinspection ReuseOfLocalVariable instanceFactory = mockedTypesAndInstances.get(mockedClass); if (instanceFactory != null) { return instanceFactory; } boolean abstractType = mockedClass.isInterface() || isAbstract(mockedClass.getModifiers()); for (Entry<Type, InstanceFactory> entry : mockedTypesAndInstances.entrySet()) { Type registeredMockedType = entry.getKey(); Class<?> registeredMockedClass = getClassType(registeredMockedType); if (abstractType) { registeredMockedClass = getMockedClassOrInterfaceType(registeredMockedClass); } if (mockedClass.isAssignableFrom(registeredMockedClass)) { instanceFactory = entry.getValue(); break; } } return instanceFactory; }
/** * Sets up the mocks defined in the given mock class. * * <p>If the type {@linkplain MockClass#realClass referred to} by the mock class is actually an * interface, then a {@linkplain #newEmptyProxy(ClassLoader, Class) new empty proxy} is created. * * @param mockClassOrInstance the mock class itself (given by its {@code Class} literal), or an * instance of the mock class * @return the new proxy instance created for the mocked interface, or {@code null} otherwise * @throws IllegalArgumentException if a given mock class fails to specify the corresponding real * class using the {@code @MockClass(realClass = ...)} annotation; or if a mock class defines * a mock method for which no corresponding real method or constructor exists in the real * class; or if the real method matching a mock method is {@code abstract} * @see #setUpMock(Class, Object) * @see #setUpMocks(Object...) * @see <a * href="http://code.google.com/p/jmockit/source/browse/trunk/main/test/mockit/MockAnnotationsTest.java#696"> * Example</a> */ public static <T> T setUpMock(Object mockClassOrInstance) { Class<?> mockClass; Object mock; if (mockClassOrInstance instanceof Class<?>) { mockClass = (Class<?>) mockClassOrInstance; mock = null; } else { mockClass = mockClassOrInstance.getClass(); mock = mockClassOrInstance; } MockClassSetup setup = new MockClassSetup(mock, mockClass); Class<?> realClass = setup.getRealClass(); T proxy = null; if (realClass.isInterface()) { //noinspection unchecked proxy = (T) newEmptyProxy(mockClass.getClassLoader(), realClass); setup.setRealClass(proxy.getClass()); } setup.redefineMethods(); return proxy; }
/** * Given a mix of {@linkplain MockClass mock} and real classes, {@linkplain #setUpMock(Class, * Class) sets up} each mock class for the associated real class, and {@linkplain #stubOut stubs * out} each specified regular class. * * @param mockAndRealClasses one or more mock classes and/or regular classes to be stubbed out */ public static void setUpMocksAndStubs(Class<?>... mockAndRealClasses) { for (Class<?> mockOrRealClass : mockAndRealClasses) { MockClass metadata = mockOrRealClass.getAnnotation(MockClass.class); if (metadata != null) { new MockClassSetup(mockOrRealClass, metadata).redefineMethods(); } else { new ClassStubbing(mockOrRealClass).stubOut(); } } }
public boolean isMockedClass(@Nonnull String targetClassName) { int n = mockedClasses.size(); for (int i = 0; i < n; i++) { Class<?> mockedClass = mockedClasses.get(i); if (targetClassName.equals(mockedClass.getName())) { return true; } } return false; }
private void restoreDefinition(@Nonnull Class<?> redefinedClass) { if (redefinedClassesWithNativeMethods.contains(redefinedClass.getName())) { reregisterNativeMethodsForRestoredClass(redefinedClass); } removeMockedClass(redefinedClass); }
public void registerMockedClass(@Nonnull Class<?> mockedType) { if (!isMockedClass(mockedType)) { if (Proxy.isProxyClass(mockedType)) { mockedType = mockedType.getInterfaces()[0]; } mockedClasses.add(mockedType); } }
private Method findPublicVoidMethod(Class<?> aClass, String methodName) { for (Method method : aClass.getDeclaredMethods()) { if (isPublic(method.getModifiers()) && method.getReturnType() == void.class && methodName.equals(method.getName())) { return method; } } return null; }
/** * The instance is stored in a place directly accessible through the Java SE API, so that it can * be recovered from any class loader. */ protected MockingBridge(Class<? extends MockingBridge> subclass) { super("mockit." + subclass.hashCode(), null); LogManager.getLogManager().addLogger(this); }
public static void preventEventualClassLoadingConflicts() { // Pre-load certain JMockit classes to avoid NoClassDefFoundError's or re-entrancy loops during // class loading // when certain JRE classes are mocked, such as ArrayList or Thread. try { Class.forName("mockit.Capturing"); Class.forName("mockit.Delegate"); Class.forName("mockit.Invocation"); Class.forName("mockit.internal.RedefinitionEngine"); Class.forName("mockit.internal.util.GeneratedClasses"); Class.forName("mockit.internal.util.MethodReflection"); Class.forName("mockit.internal.util.ObjectMethods"); Class.forName("mockit.internal.util.TypeDescriptor"); Class.forName("mockit.internal.expectations.RecordAndReplayExecution"); Class.forName("mockit.internal.expectations.invocation.InvocationResults"); Class.forName("mockit.internal.expectations.invocation.MockedTypeCascade"); Class.forName("mockit.internal.expectations.mocking.BaseTypeRedefinition$MockedClass"); Class.forName("mockit.internal.expectations.mocking.SharedFieldTypeRedefinitions"); Class.forName("mockit.internal.expectations.mocking.TestedClasses"); Class.forName("mockit.internal.expectations.argumentMatching.EqualityMatcher"); } catch (ClassNotFoundException ignore) { } wasCalledDuringClassLoading(); DefaultValues.computeForReturnType("()J"); }
/** * Same as {@link #newEmptyProxy(ClassLoader, Class)}, but with the class loader obtained from the * interface to be proxied. Note that this may lead to a {@code NoClassDefFoundError} if that * interface was loaded by the boot class loader (usually, when it's a JRE class). Therefore, you * should only use this method for application-defined interfaces. * * <p>This method is just a convenience for some uses of the <em>Mockups</em> API. In <em>JMockit * Expectations</em> in particular, mocked instances will be automatically created and assigned to * any mock fields or parameters. * * @see <a * href="http://code.google.com/p/jmockit/source/browse/trunk/main/test/integrationTests/textFile/TextFileUsingAnnotatedMockClassesTest.java#91"> * Example</a> */ public static <E> E newEmptyProxy(Class<E> interfaceToBeProxied) { return newEmptyProxy(interfaceToBeProxied.getClassLoader(), interfaceToBeProxied); }