Skip to content

Commit

Permalink
Fix issue #731 No methods matching the name(s) get were found in the …
Browse files Browse the repository at this point in the history
…class hierarchy for interfaces
  • Loading branch information
Arthur Zagretdinov committed Jan 28, 2017
1 parent ddda468 commit 53bdb4c
Show file tree
Hide file tree
Showing 19 changed files with 439 additions and 193 deletions.
1 change: 1 addition & 0 deletions changelog.txt
Expand Up @@ -5,6 +5,7 @@ Change log 1.7.0
* Support Mockito 2.4.0 for PowerMock 1.x (thanks to Gregor Stamac @gstamac for pull request)
* Fix issue #722 IllegalArgumentException is output to standard error (thanks to Kotaro Nanri @k-nanri for pull request)
* Fix issue #717 Regression: MethodNotFoundException
* Fix issue #731 No methods matching the name(s) get were found in the class hierarchy for interfaces

Change log 1.6.6 (2016-11-04)
-----------------------------
Expand Down
Expand Up @@ -1618,7 +1618,7 @@ private static <T> IExpectationSetters<T> doExpectNew(Class<T> type, MockStrateg

final boolean isNiceMock = mockStrategy instanceof NiceMockStrategy;

final Class<T> unmockedType = (Class<T>) WhiteboxImpl.getUnmockedType(type);
final Class<T> unmockedType = (Class<T>) WhiteboxImpl.getOriginalUnmockedType(type);
if (!isNiceMock) {
if (parameterTypes == null) {
WhiteboxImpl.findUniqueConstructorOrThrowException(type, arguments);
Expand All @@ -1637,7 +1637,7 @@ private static <T> IExpectationSetters<T> doExpectNew(Class<T> type, MockStrateg
(Method[]) null);
newInvocationControl = new NewInvocationControlImpl<T>(mock, type);
MockRepository.putNewInstanceControl(type, newInvocationControl);
MockRepository.addObjectsToAutomaticallyReplayAndVerify(WhiteboxImpl.getUnmockedType(type));
MockRepository.addObjectsToAutomaticallyReplayAndVerify(WhiteboxImpl.getOriginalUnmockedType(type));
}

if (isNiceMock && (arguments == null || arguments.length == 0)) {
Expand Down
Expand Up @@ -13,7 +13,6 @@

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public abstract class AbstractConstructorExpectationSetup<T> implements ConstructorExpectationSetup<T> {

Expand All @@ -33,7 +32,7 @@ private <T> OngoingStubbing<T> createNewSubstituteMock(Class<T> type, Class<?>[]
throw new IllegalArgumentException("type cannot be null");
}

final Class<T> unmockedType = (Class<T>) WhiteboxImpl.getUnmockedType(type);
final Class<T> unmockedType = (Class<T>) WhiteboxImpl.getOriginalUnmockedType(type);
if (parameterTypes == null) {
WhiteboxImpl.findUniqueConstructorOrThrowException(type, arguments);
} else {
Expand All @@ -49,7 +48,7 @@ private <T> OngoingStubbing<T> createNewSubstituteMock(Class<T> type, Class<?>[]
InvocationSubstitute<T> mock = getMockCreator().createMock(InvocationSubstitute.class, false, false, null, null, (Method[]) null);
newInvocationControl = createNewInvocationControl(mock);
MockRepository.putNewInstanceControl(type, newInvocationControl);
MockRepository.addObjectsToAutomaticallyReplayAndVerify(WhiteboxImpl.getUnmockedType(type));
MockRepository.addObjectsToAutomaticallyReplayAndVerify(WhiteboxImpl.getOriginalUnmockedType(type));
}

return newInvocationControl.expectSubstitutionLogic(arguments);
Expand Down Expand Up @@ -77,7 +76,7 @@ public OngoingStubbing<T> withAnyArguments() throws Exception {
if (mockType == null) {
throw new IllegalArgumentException("Class to expected cannot be null");
}
final Class<T> unmockedType = (Class<T>) WhiteboxImpl.getUnmockedType(mockType);
final Class<T> unmockedType = (Class<T>) WhiteboxImpl.getOriginalUnmockedType(mockType);
final Constructor<?>[] allConstructors = WhiteboxImpl.getAllConstructors(unmockedType);
final Constructor<?> constructor = allConstructors[0];
final Class<?>[] parameterTypes = constructor.getParameterTypes();
Expand Down
68 changes: 1 addition & 67 deletions powermock-core/src/main/java/org/powermock/core/MockGateway.java
Expand Up @@ -17,13 +17,11 @@

import org.powermock.core.spi.MethodInvocationControl;
import org.powermock.core.spi.NewInvocationControl;
import org.powermock.reflect.exceptions.MethodNotFoundException;
import org.powermock.reflect.internal.TypeUtils;
import org.powermock.reflect.internal.WhiteboxImpl;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
Expand Down Expand Up @@ -302,69 +300,5 @@ private static Object[] copyArgumentsForInnerOrLocalOrAnonymousClass(Object[] ar
args = newArgs;
return args;
}

private static class MockInvocation {
private Object object;
private String methodName;
private Class<?>[] sig;
private Class<?> objectType;
private MethodInvocationControl methodInvocationControl;
private Method method;

public MockInvocation(Object object, String methodName, Class<?>... sig) {
this.object = object;
this.methodName = methodName;
this.sig = sig;
init();
}

private static Method findMethodToInvoke(String methodName, Class<?>[] sig, Class<?> objectType) {/*
* if invocationControl is null or the method is not mocked, invoke
* original method or suppress the method code otherwise invoke the
* invocation handler.
*/
Method method;
try {
method = WhiteboxImpl.getBestMethodCandidate(objectType, methodName, sig, true);
} catch (MethodNotFoundException e) {
/*
* Dirty hack to get around issue 110
* (http://code.google.com/p/powermock/issues/detail?id=110). Review
* this! What we do here is to try to find a reflective method on
* class. This has begun to fail since version 1.2 when we supported
* mocking static methods in system classes.
*/
try {
method = WhiteboxImpl.getMethod(Class.class, methodName, sig);
} catch (MethodNotFoundException e2) {
throw e;
}
}
return method;
}

public Class<?> getObjectType() {
return objectType;
}

public MethodInvocationControl getMethodInvocationControl() {
return methodInvocationControl;
}

public Method getMethod() {
return method;
}

private void init() {
if (object instanceof Class<?>) {
objectType = (Class<?>) object;
methodInvocationControl = MockRepository.getStaticMethodInvocationControl(objectType);
} else {
final Class<?> type = object.getClass();
objectType = WhiteboxImpl.getUnmockedType(type);
methodInvocationControl = MockRepository.getInstanceMethodInvocationControl(object);
}
method = findMethodToInvoke(methodName, sig, objectType);
}
}

}
@@ -0,0 +1,75 @@
package org.powermock.core;

import org.powermock.core.spi.MethodInvocationControl;
import org.powermock.reflect.exceptions.MethodNotFoundException;
import org.powermock.reflect.internal.WhiteboxImpl;
import org.powermock.reflect.internal.proxy.UnproxiedType;

import java.lang.reflect.Method;

class MockInvocation {
private Object object;
private String methodName;
private Class<?>[] sig;
private Class<?> objectType;
private MethodInvocationControl methodInvocationControl;
private Method method;

MockInvocation(Object object, String methodName, Class<?>... sig) {
this.object = object;
this.methodName = methodName;
this.sig = sig;
init();
}

private void init() {
if (object instanceof Class<?>) {
objectType = (Class<?>) object;
methodInvocationControl = MockRepository.getStaticMethodInvocationControl(objectType);
} else {
final Class<?> type = object.getClass();
UnproxiedType unproxiedType = WhiteboxImpl.getUnproxiedType(type);
objectType = unproxiedType.getOriginalType();
methodInvocationControl = MockRepository.getInstanceMethodInvocationControl(object);
}
method = findMethodToInvoke(methodName, sig, objectType);
}

Class<?> getObjectType() {
return objectType;
}

MethodInvocationControl getMethodInvocationControl() {
return methodInvocationControl;
}

Method getMethod() {
return method;
}

private static Method findMethodToInvoke(String methodName, Class<?>[] sig, Class<?> objectType) {
/*
* if invocationControl is null or the method is not mocked, invoke
* original method or suppress the method code otherwise invoke the
* invocation handler.
*/
Method method;
try {
method = WhiteboxImpl.getBestMethodCandidate(objectType, methodName, sig, true);
} catch (MethodNotFoundException e) {
/*
* Dirty hack to get around issue 110
* (http://code.google.com/p/powermock/issues/detail?id=110). Review
* this! What we do here is to try to find a reflective method on
* class. This has begun to fail since version 1.2 when we supported
* mocking static methods in system classes.
*/
try {
method = WhiteboxImpl.getMethod(Class.class, methodName, sig);
} catch (MethodNotFoundException e2) {
throw e;
}
}
return method;
}
}
Expand Up @@ -20,7 +20,7 @@ class ConstructorFinder {

this.type = type;
this.arguments = arguments;
this.unmockedType = WhiteboxImpl.getUnmockedType(type);
this.unmockedType = WhiteboxImpl.getOriginalUnmockedType(type);

if (isNestedClass() && arguments != null) {
addArgumentForNestedClass();
Expand Down Expand Up @@ -119,7 +119,7 @@ private boolean isPowerMockConstructor(Class<?>[] parameterTypes) {

private void throwExceptionIfConstructorWasNotFound() {
if (potentialConstructor == null) {
String message = "No constructor found in class '" + WhiteboxImpl.getUnmockedType(type).getName() + "' " +
String message = "No constructor found in class '" + WhiteboxImpl.getOriginalUnmockedType(type).getName() + "' " +
"with "
+ "parameter types: [ " + WhiteboxImpl.getArgumentTypesAsString(arguments) + " ].";
throw new ConstructorNotFoundException(message);
Expand Down
Expand Up @@ -35,6 +35,7 @@
import org.powermock.reflect.internal.primitivesupport.BoxedWrapper;
import org.powermock.reflect.internal.primitivesupport.PrimitiveWrapper;
import org.powermock.reflect.internal.proxy.ProxyFrameworks;
import org.powermock.reflect.internal.proxy.UnproxiedType;
import org.powermock.reflect.matching.FieldMatchingStrategy;

import java.lang.annotation.Annotation;
Expand Down Expand Up @@ -129,7 +130,7 @@ public static Method getMethod(Class<?> type, Class<?>... parameterTypes) {
if (foundMethods.isEmpty()) {
throw new MethodNotFoundException("No method was found with parameter types: [ "
+ getArgumentTypesAsString((Object[]) parameterTypes) + " ] in class "
+ getUnmockedType(type).getName() + ".");
+ getOriginalUnmockedType(type).getName() + ".");
} else {
throwExceptionWhenMultipleMethodMatchesFound("method name",
foundMethods.toArray(new Method[foundMethods.size()]));
Expand Down Expand Up @@ -273,7 +274,7 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
* @return A .
*/
public static Constructor<?> getConstructor(Class<?> type, Class<?>... parameterTypes) {
Class<?> unmockedType = WhiteboxImpl.getUnmockedType(type);
Class<?> unmockedType = WhiteboxImpl.getOriginalUnmockedType(type);
try {
final Constructor<?> constructor = unmockedType.getDeclaredConstructor(parameterTypes);
constructor.setAccessible(true);
Expand Down Expand Up @@ -1117,7 +1118,7 @@ public static void throwExceptionIfMethodWasNotFound(Class<?> type, String metho
methodNameData = "with name '" + methodName + "' ";
}
throw new MethodNotFoundException("No method found " + methodNameData + "with parameter types: [ "
+ getArgumentTypesAsString(arguments) + " ] in class " + getUnmockedType(type)
+ getArgumentTypesAsString(arguments) + " ] in class " + getOriginalUnmockedType(type)
.getName() + ".");
}
}
Expand All @@ -1132,7 +1133,7 @@ public static void throwExceptionIfMethodWasNotFound(Class<?> type, String metho
public static void throwExceptionIfFieldWasNotFound(Class<?> type, String fieldName, Field field) {
if (field == null) {
throw new FieldNotFoundException("No field was found with name '" + fieldName + "' in class "
+ getUnmockedType(type).getName() + ".");
+ getOriginalUnmockedType(type).getName() + ".");
}
}

Expand All @@ -1146,7 +1147,7 @@ public static void throwExceptionIfFieldWasNotFound(Class<?> type, String fieldN
static void throwExceptionIfConstructorWasNotFound(Class<?> type, Constructor<?> potentialConstructor,
Object... arguments) {
if (potentialConstructor == null) {
String message = "No constructor found in class '" + getUnmockedType(type).getName() + "' with "
String message = "No constructor found in class '" + getOriginalUnmockedType(type).getName() + "' with "
+ "parameter types: [ " + getArgumentTypesAsString(arguments) + " ].";
throw new ConstructorNotFoundException(message);
}
Expand Down Expand Up @@ -1553,7 +1554,7 @@ public static Field[] getAllFields(Class<?> clazz) {
*/
public static Constructor<?> getFirstParentConstructor(Class<?> klass) {
try {
return getUnmockedType(klass).getSuperclass().getDeclaredConstructors()[0];
return getOriginalUnmockedType(klass).getSuperclass().getDeclaredConstructors()[0];
} catch (Exception e) {
throw new ConstructorNotFoundException("Failed to lookup constructor.", e);
}
Expand Down Expand Up @@ -1634,10 +1635,14 @@ public static <T> Method findMethod(Class<T> type, String methodName, Class<?>..
* @param type the type
* @return the unmocked type
*/
public static <T> Class<?> getUnmockedType(Class<T> type) {
public static <T> Class<?> getOriginalUnmockedType(Class<T> type) {
return getUnproxiedType(type).getOriginalType();
}

public static <T> UnproxiedType getUnproxiedType(Class<T> type) {
return proxyFrameworks.getUnproxiedType(type);
}

/**
* Throw exception when multiple method matches found.
*
Expand Down Expand Up @@ -1898,7 +1903,7 @@ public static <T> Method[] getAllMethodsExcept(Class<T> type, String methodNameT
final Class<?>[] args = method.getParameterTypes();
if (args != null && args.length == argumentTypes.length) {
for (int i = 0; i < args.length; i++) {
if (args[i].isAssignableFrom(getUnmockedType(argumentTypes[i]))) {
if (args[i].isAssignableFrom(getOriginalUnmockedType(argumentTypes[i]))) {
/*
* Method was not found thus it should not be
* mocked. Continue to investigate the next
Expand Down Expand Up @@ -2066,7 +2071,7 @@ public static Class<?> getUnproxyType(Object object) {
} else if (object != null) {
type = object.getClass();
}
return type == null ? null : getUnmockedType(type);
return type == null ? null : getOriginalUnmockedType(type);
}

/**
Expand Down
Expand Up @@ -4,42 +4,38 @@
import java.lang.reflect.Proxy;

public class ProxyFrameworks {

private static final UnproxiedTypeFactory UNPROXIED_TYPE_FACTORY = new UnproxiedTypeFactory();

public Class<?> getUnproxiedType(Class<?> type) {
public UnproxiedType getUnproxiedType(Class<?> type) {

if (type == null){
return null;
}

if (isJavaProxy(type)){
return type.getInterfaces()[0];
return UNPROXIED_TYPE_FACTORY.createFromInterfaces(type.getInterfaces());
}

if (isCglibProxyClass(type)) {
return type.getSuperclass();
return UNPROXIED_TYPE_FACTORY.createFromSuperclassAndInterfaces(type.getSuperclass(), type.getInterfaces());
}


return type;
return UNPROXIED_TYPE_FACTORY.createFromType(type);
}

private boolean isJavaProxy(Class<?> clazz) {
return (clazz != null && Proxy.isProxyClass(clazz));
}

public Class<?> getUnproxiedType(Object o) {

public UnproxiedType getUnproxiedType(Object o) {
if (o == null) {
throw new IllegalArgumentException("type cannot be null");
return null;
}
return getUnproxiedType(o.getClass());
}

/**
* Check whether the specified class is a CGLIB-generated class.
*
* @param clazz the class to check
*/
public boolean isCglibProxyClass(Class<?> clazz) {
private boolean isJavaProxy(Class<?> clazz) {
return (clazz != null && Proxy.isProxyClass(clazz));
}

private boolean isCglibProxyClass(Class<?> clazz) {
if (clazz == null){
return false;
}
Expand Down

0 comments on commit 53bdb4c

Please sign in to comment.