From c7b56e022669975fe1af47636477bea8ee64c181 Mon Sep 17 00:00:00 2001 From: Tomas Poledny <saljacky@gmail.com> Date: Sat, 15 May 2021 23:43:20 +0200 Subject: [PATCH] Add method name check for generic methods Expectations --- .../invocation/ExpectedInvocation.java | 8 +++- .../mockit/CapturingImplementationsTest.java | 48 +++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/main/src/mockit/internal/expectations/invocation/ExpectedInvocation.java b/main/src/mockit/internal/expectations/invocation/ExpectedInvocation.java index 1dea784f2..bef98071a 100644 --- a/main/src/mockit/internal/expectations/invocation/ExpectedInvocation.java +++ b/main/src/mockit/internal/expectations/invocation/ExpectedInvocation.java @@ -113,7 +113,7 @@ private boolean isMatchingGenericMethod(@Nullable Object mock, @Nonnull String i if (mockedClass != instance.getClass()) { GenericTypeReflection typeReflection = new GenericTypeReflection(mockedClass, null); GenericSignature parsedSignature = typeReflection.parseSignature(genericSignature); - return parsedSignature.satisfiesSignature(invokedMethod); + return parsedSignature.satisfiesSignature(invokedMethod) && isMatchingMethodName(invokedMethod); } } } @@ -137,6 +137,12 @@ private boolean isMatchingMethod(@Nonnull String invokedMethod) { return isReturnTypeOfRecordedMethodAssignableToReturnTypeOfInvokedMethod(invokedMethod, returnTypeStartPos); } + private boolean isMatchingMethodName(@Nonnull String invokedMethod) { + int methodNameEndPos = invokedMethod.indexOf('('); + String methodName = invokedMethod.substring(0, methodNameEndPos + 1); + return getMethodNameAndDescription().startsWith(methodName); + } + // Returns -1 if the method names or parameters are different. private int getReturnTypePosition(@Nonnull String invokedMethod) { String recordedMethod = getMethodNameAndDescription(); diff --git a/main/test/mockit/CapturingImplementationsTest.java b/main/test/mockit/CapturingImplementationsTest.java index 4d1942fd0..5f5b5c7d0 100644 --- a/main/test/mockit/CapturingImplementationsTest.java +++ b/main/test/mockit/CapturingImplementationsTest.java @@ -196,22 +196,26 @@ public void captureClassWhichImplementsCapturedBaseInterfaceAndExtendsUnrelatedB static class Base<T> { T doSomething() { return null; } void doSomething(T t) { System.out.println("test");} + T doSomethingReturn(T t) { return t;} } static final class Impl extends Base<Integer> { @Override Integer doSomething() { return 1; } @Override void doSomething(Integer i) {} + @Override Integer doSomethingReturn(Integer t) { return null;} } @Test public void captureImplementationsOfGenericType(@Capturing final Base<Integer> anyInstance) { new Expectations() {{ anyInstance.doSomething(); result = 2; + anyInstance.doSomethingReturn(0); anyInstance.doSomething(0); }}; Base<Integer> impl = new Impl(); int i = impl.doSomething(); + impl.doSomethingReturn(0); impl.doSomething(0); assertEquals(2, i); @@ -263,4 +267,48 @@ public void captureLibraryClassImplementingInterfaceFromAnotherLibrary(@Capturin new Verifications() {{ mock.contextInitialized(null); }}; } + + static class BaseGenericReturnTypes { + Class<?> methodOne() {return null;} + Class<?> methodTwo() {return null;} + } + static class SubGenericReturnTypes extends BaseGenericReturnTypes {} + + @Test + public void captureMethodWithGenericReturnTypes(@Capturing final BaseGenericReturnTypes mock) { + new Expectations () {{ + mock.methodOne(); + result = BaseGenericReturnTypes.class; + times = 1; + + mock.methodTwo(); + result = SubGenericReturnTypes.class; + times = 1; + }}; + SubGenericReturnTypes subBaseGenericReturnTypes = new SubGenericReturnTypes(); + assertEquals(BaseGenericReturnTypes.class, subBaseGenericReturnTypes.methodOne()); + assertEquals(SubGenericReturnTypes.class, subBaseGenericReturnTypes.methodTwo()); + } + + static class BaseR { + void foo() {}; + void bar() {}; + } + + static class SubR extends BaseR {} + + @Test + public void captureR(@Capturing final BaseR mock) { + new Expectations () {{ + mock.foo(); + times = 1; + + mock.bar(); + times = 1; + }}; + SubR subR = new SubR(); + subR.foo(); + subR.bar(); + } + } \ No newline at end of file