summaryrefslogtreecommitdiff
path: root/src/main/java/org/mockito/internal
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/mockito/internal')
-rw-r--r--src/main/java/org/mockito/internal/MockitoCore.java25
-rw-r--r--src/main/java/org/mockito/internal/configuration/InjectingAnnotationEngine.java10
-rw-r--r--src/main/java/org/mockito/internal/configuration/MockAnnotationProcessor.java3
-rw-r--r--src/main/java/org/mockito/internal/configuration/plugins/DefaultMockitoPlugins.java2
-rw-r--r--src/main/java/org/mockito/internal/configuration/plugins/PluginRegistry.java16
-rw-r--r--src/main/java/org/mockito/internal/configuration/plugins/Plugins.java11
-rw-r--r--src/main/java/org/mockito/internal/creation/MockSettingsImpl.java28
-rw-r--r--src/main/java/org/mockito/internal/creation/SuspendMethod.java10
-rw-r--r--src/main/java/org/mockito/internal/creation/bytebuddy/InlineByteBuddyMockMaker.java27
-rw-r--r--src/main/java/org/mockito/internal/creation/bytebuddy/InlineBytecodeGenerator.java53
-rw-r--r--src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodAdvice.java3
-rw-r--r--src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodInterceptor.java32
-rw-r--r--src/main/java/org/mockito/internal/creation/bytebuddy/ModuleHandler.java251
-rw-r--r--src/main/java/org/mockito/internal/creation/bytebuddy/SubclassBytecodeGenerator.java166
-rw-r--r--src/main/java/org/mockito/internal/creation/bytebuddy/SubclassInjectionLoader.java37
-rw-r--r--src/main/java/org/mockito/internal/creation/bytebuddy/SubclassLoader.java11
-rw-r--r--src/main/java/org/mockito/internal/creation/bytebuddy/inject/MockMethodDispatcher.java35
-rw-r--r--src/main/java/org/mockito/internal/creation/bytebuddy/inject/package-info.java11
-rw-r--r--src/main/java/org/mockito/internal/creation/settings/CreationSettings.java12
-rw-r--r--src/main/java/org/mockito/internal/debugging/LocationImpl.java13
-rw-r--r--src/main/java/org/mockito/internal/exceptions/Reporter.java35
-rw-r--r--src/main/java/org/mockito/internal/exceptions/stacktrace/StackTraceFilter.java13
-rw-r--r--src/main/java/org/mockito/internal/framework/DefaultMockitoFramework.java23
-rw-r--r--src/main/java/org/mockito/internal/framework/DefaultMockitoSession.java14
-rw-r--r--src/main/java/org/mockito/internal/invocation/InterceptedInvocation.java27
-rw-r--r--src/main/java/org/mockito/internal/invocation/InvocationMatcher.java3
-rw-r--r--src/main/java/org/mockito/internal/junit/DefaultStubbingLookupListener.java16
-rw-r--r--src/main/java/org/mockito/internal/junit/ExceptionFactory.java65
-rw-r--r--src/main/java/org/mockito/internal/junit/JUnitRule.java19
-rw-r--r--src/main/java/org/mockito/internal/junit/MismatchReportingTestListener.java2
-rw-r--r--src/main/java/org/mockito/internal/junit/StrictStubsRunnerTestListener.java7
-rw-r--r--src/main/java/org/mockito/internal/junit/StubbingArgMismatches.java2
-rw-r--r--src/main/java/org/mockito/internal/junit/UniversalTestListener.java21
-rw-r--r--src/main/java/org/mockito/internal/junit/UnusedStubbings.java2
-rw-r--r--src/main/java/org/mockito/internal/junit/VerificationCollectorImpl.java4
-rw-r--r--src/main/java/org/mockito/internal/listeners/AutoCleanableListener.java17
-rw-r--r--src/main/java/org/mockito/internal/listeners/StubbingLookupNotifier.java2
-rw-r--r--src/main/java/org/mockito/internal/progress/MockingProgressImpl.java23
-rw-r--r--src/main/java/org/mockito/internal/reporting/PrintSettings.java3
-rw-r--r--src/main/java/org/mockito/internal/runners/DefaultInternalRunner.java31
-rw-r--r--src/main/java/org/mockito/internal/runners/RunnerFactory.java4
-rw-r--r--src/main/java/org/mockito/internal/session/DefaultMockitoSessionBuilder.java6
-rw-r--r--src/main/java/org/mockito/internal/session/MockitoLoggerAdapter.java2
-rw-r--r--src/main/java/org/mockito/internal/session/MockitoSessionLoggerAdapter.java2
-rw-r--r--src/main/java/org/mockito/internal/stubbing/BaseStubbing.java28
-rw-r--r--src/main/java/org/mockito/internal/stubbing/ConsecutiveStubbing.java18
-rw-r--r--src/main/java/org/mockito/internal/stubbing/OngoingStubbingImpl.java12
-rw-r--r--src/main/java/org/mockito/internal/stubbing/StubberImpl.java12
-rw-r--r--src/main/java/org/mockito/internal/stubbing/answers/AnswerFunctionalInterfaces.java58
-rw-r--r--src/main/java/org/mockito/internal/stubbing/defaultanswers/ForwardsInvocations.java5
-rw-r--r--src/main/java/org/mockito/internal/stubbing/defaultanswers/RetrieveGenericsForDefaultAnswers.java138
-rw-r--r--src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsDeepStubs.java45
-rwxr-xr-xsrc/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsMocks.java35
-rw-r--r--src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsSmartNulls.java28
-rw-r--r--src/main/java/org/mockito/internal/util/ConsoleMockitoLogger.java2
-rw-r--r--src/main/java/org/mockito/internal/util/reflection/GenericMetadataSupport.java102
-rw-r--r--src/main/java/org/mockito/internal/verification/VerificationWrapperInOrderWrapper.java1
57 files changed, 361 insertions, 1222 deletions
diff --git a/src/main/java/org/mockito/internal/MockitoCore.java b/src/main/java/org/mockito/internal/MockitoCore.java
index 5d39d5e..68b580a 100644
--- a/src/main/java/org/mockito/internal/MockitoCore.java
+++ b/src/main/java/org/mockito/internal/MockitoCore.java
@@ -35,17 +35,24 @@ import org.mockito.verification.VerificationMode;
import java.util.Arrays;
import java.util.List;
-import static org.mockito.internal.exceptions.Reporter.*;
+import static org.mockito.internal.exceptions.Reporter.missingMethodInvocation;
+import static org.mockito.internal.exceptions.Reporter.mocksHaveToBePassedToVerifyNoMoreInteractions;
+import static org.mockito.internal.exceptions.Reporter.mocksHaveToBePassedWhenCreatingInOrder;
+import static org.mockito.internal.exceptions.Reporter.notAMockPassedToVerify;
+import static org.mockito.internal.exceptions.Reporter.notAMockPassedToVerifyNoMoreInteractions;
+import static org.mockito.internal.exceptions.Reporter.notAMockPassedWhenCreatingInOrder;
+import static org.mockito.internal.exceptions.Reporter.nullPassedToVerify;
+import static org.mockito.internal.exceptions.Reporter.nullPassedToVerifyNoMoreInteractions;
+import static org.mockito.internal.exceptions.Reporter.nullPassedWhenCreatingInOrder;
+import static org.mockito.internal.exceptions.Reporter.stubPassedToVerify;
import static org.mockito.internal.progress.ThreadSafeMockingProgress.mockingProgress;
import static org.mockito.internal.util.MockUtil.createMock;
import static org.mockito.internal.util.MockUtil.getInvocationContainer;
-import static org.mockito.internal.util.MockUtil.getMockHandler;
import static org.mockito.internal.util.MockUtil.isMock;
import static org.mockito.internal.util.MockUtil.resetMock;
import static org.mockito.internal.util.MockUtil.typeMockabilityOf;
import static org.mockito.internal.verification.VerificationModeFactory.noMoreInteractions;
-
@SuppressWarnings("unchecked")
public class MockitoCore {
@@ -84,8 +91,10 @@ public class MockitoCore {
if (!mockingDetails.isMock()) {
throw notAMockPassedToVerify(mock.getClass());
}
- assertNotStubOnlyMock(mock);
MockHandler handler = mockingDetails.getMockHandler();
+ if (handler.getMockSettings().isStubOnly()) {
+ throw stubPassedToVerify();
+ }
mock = (T) VerificationStartedNotifier.notifyVerificationStarted(
handler.getMockSettings().getVerificationStartedListeners(), mockingDetails);
@@ -126,7 +135,6 @@ public class MockitoCore {
throw nullPassedToVerifyNoMoreInteractions();
}
InvocationContainerImpl invocations = getInvocationContainer(mock);
- assertNotStubOnlyMock(mock);
VerificationDataImpl data = new VerificationDataImpl(invocations, null);
noMoreInteractions().verify(data);
} catch (NotAMockException e) {
@@ -147,12 +155,6 @@ public class MockitoCore {
}
}
- private void assertNotStubOnlyMock(Object mock) {
- if (getMockHandler(mock).getMockSettings().isStubOnly()) {
- throw stubPassedToVerify(mock);
- }
- }
-
public InOrder inOrder(Object... mocks) {
if (mocks == null || mocks.length == 0) {
throw mocksHaveToBePassedWhenCreatingInOrder();
@@ -164,7 +166,6 @@ public class MockitoCore {
if (!isMock(mock)) {
throw notAMockPassedWhenCreatingInOrder();
}
- assertNotStubOnlyMock(mock);
}
return new InOrderImpl(Arrays.asList(mocks));
}
diff --git a/src/main/java/org/mockito/internal/configuration/InjectingAnnotationEngine.java b/src/main/java/org/mockito/internal/configuration/InjectingAnnotationEngine.java
index 20d967d..6cb5fb1 100644
--- a/src/main/java/org/mockito/internal/configuration/InjectingAnnotationEngine.java
+++ b/src/main/java/org/mockito/internal/configuration/InjectingAnnotationEngine.java
@@ -39,7 +39,15 @@ public class InjectingAnnotationEngine implements AnnotationEngine, org.mockito.
*/
public void process(Class<?> clazz, Object testInstance) {
processIndependentAnnotations(testInstance.getClass(), testInstance);
- injectMocks(testInstance);
+ processInjectMocks(testInstance.getClass(), testInstance);
+ }
+
+ private void processInjectMocks(final Class<?> clazz, final Object testInstance) {
+ Class<?> classContext = clazz;
+ while (classContext != Object.class) {
+ injectMocks(testInstance);
+ classContext = classContext.getSuperclass();
+ }
}
private void processIndependentAnnotations(final Class<?> clazz, final Object testInstance) {
diff --git a/src/main/java/org/mockito/internal/configuration/MockAnnotationProcessor.java b/src/main/java/org/mockito/internal/configuration/MockAnnotationProcessor.java
index d99b348..91086d2 100644
--- a/src/main/java/org/mockito/internal/configuration/MockAnnotationProcessor.java
+++ b/src/main/java/org/mockito/internal/configuration/MockAnnotationProcessor.java
@@ -35,9 +35,6 @@ public class MockAnnotationProcessor implements FieldAnnotationProcessor<Mock> {
if(annotation.stubOnly()){
mockSettings.stubOnly();
}
- if(annotation.lenient()){
- mockSettings.lenient();
- }
// see @Mock answer default value
mockSettings.defaultAnswer(annotation.answer());
diff --git a/src/main/java/org/mockito/internal/configuration/plugins/DefaultMockitoPlugins.java b/src/main/java/org/mockito/internal/configuration/plugins/DefaultMockitoPlugins.java
index e5aefd9..f80e7c4 100644
--- a/src/main/java/org/mockito/internal/configuration/plugins/DefaultMockitoPlugins.java
+++ b/src/main/java/org/mockito/internal/configuration/plugins/DefaultMockitoPlugins.java
@@ -9,7 +9,6 @@ import org.mockito.plugins.AnnotationEngine;
import org.mockito.plugins.InstantiatorProvider;
import org.mockito.plugins.InstantiatorProvider2;
import org.mockito.plugins.MockMaker;
-import org.mockito.plugins.MockitoLogger;
import org.mockito.plugins.MockitoPlugins;
import org.mockito.plugins.PluginSwitch;
import org.mockito.plugins.StackTraceCleanerProvider;
@@ -30,7 +29,6 @@ class DefaultMockitoPlugins implements MockitoPlugins {
DEFAULT_PLUGINS.put(InstantiatorProvider2.class.getName(), "org.mockito.internal.creation.instance.DefaultInstantiatorProvider");
DEFAULT_PLUGINS.put(AnnotationEngine.class.getName(), "org.mockito.internal.configuration.InjectingAnnotationEngine");
DEFAULT_PLUGINS.put(INLINE_ALIAS, "org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker");
- DEFAULT_PLUGINS.put(MockitoLogger.class.getName(), "org.mockito.internal.util.ConsoleMockitoLogger");
}
@Override
diff --git a/src/main/java/org/mockito/internal/configuration/plugins/PluginRegistry.java b/src/main/java/org/mockito/internal/configuration/plugins/PluginRegistry.java
index 2e5f069..02e5d66 100644
--- a/src/main/java/org/mockito/internal/configuration/plugins/PluginRegistry.java
+++ b/src/main/java/org/mockito/internal/configuration/plugins/PluginRegistry.java
@@ -9,7 +9,6 @@ import org.mockito.plugins.AnnotationEngine;
import org.mockito.plugins.InstantiatorProvider;
import org.mockito.plugins.InstantiatorProvider2;
import org.mockito.plugins.MockMaker;
-import org.mockito.plugins.MockitoLogger;
import org.mockito.plugins.PluginSwitch;
import org.mockito.plugins.StackTraceCleanerProvider;
@@ -26,12 +25,9 @@ class PluginRegistry {
private final InstantiatorProvider2 instantiatorProvider;
- private final AnnotationEngine annotationEngine = new PluginLoader(pluginSwitch)
+ private AnnotationEngine annotationEngine = new PluginLoader(pluginSwitch)
.loadPlugin(AnnotationEngine.class);
- private final MockitoLogger mockitoLogger = new PluginLoader(pluginSwitch)
- .loadPlugin(MockitoLogger.class);
-
PluginRegistry() {
Object impl = new PluginLoader(pluginSwitch).loadPlugin(InstantiatorProvider2.class, InstantiatorProvider.class);
if (impl instanceof InstantiatorProvider) {
@@ -79,14 +75,4 @@ class PluginRegistry {
AnnotationEngine getAnnotationEngine() {
return annotationEngine;
}
-
- /**
- * Returns the logger available for the current runtime.
- *
- * <p>Returns {@link org.mockito.internal.util.ConsoleMockitoLogger} if no
- * {@link org.mockito.plugins.MockitoLogger} extension exists or is visible in the current classpath.</p>
- */
- MockitoLogger getMockitoLogger() {
- return mockitoLogger;
- }
}
diff --git a/src/main/java/org/mockito/internal/configuration/plugins/Plugins.java b/src/main/java/org/mockito/internal/configuration/plugins/Plugins.java
index 84e3c0d..f65fe89 100644
--- a/src/main/java/org/mockito/internal/configuration/plugins/Plugins.java
+++ b/src/main/java/org/mockito/internal/configuration/plugins/Plugins.java
@@ -4,7 +4,6 @@
*/
package org.mockito.internal.configuration.plugins;
-import org.mockito.plugins.MockitoLogger;
import org.mockito.plugins.AnnotationEngine;
import org.mockito.plugins.InstantiatorProvider2;
import org.mockito.plugins.MockMaker;
@@ -57,16 +56,6 @@ public class Plugins {
}
/**
- * Returns the logger available for the current runtime.
- *
- * <p>Returns {@link org.mockito.internal.util.ConsoleMockitoLogger} if no
- * {@link org.mockito.plugins.MockitoLogger} extension exists or is visible in the current classpath.</p>
- */
- public static MockitoLogger getMockitoLogger() {
- return registry.getMockitoLogger();
- }
-
- /**
* @return instance of mockito plugins type
*/
public static MockitoPlugins getPlugins() {
diff --git a/src/main/java/org/mockito/internal/creation/MockSettingsImpl.java b/src/main/java/org/mockito/internal/creation/MockSettingsImpl.java
index 50134b4..ca67730 100644
--- a/src/main/java/org/mockito/internal/creation/MockSettingsImpl.java
+++ b/src/main/java/org/mockito/internal/creation/MockSettingsImpl.java
@@ -11,7 +11,6 @@ import org.mockito.internal.util.Checks;
import org.mockito.internal.util.MockCreationValidator;
import org.mockito.internal.util.MockNameImpl;
import org.mockito.listeners.InvocationListener;
-import org.mockito.listeners.StubbingLookupListener;
import org.mockito.listeners.VerificationStartedListener;
import org.mockito.mock.MockCreationSettings;
import org.mockito.mock.MockName;
@@ -20,17 +19,17 @@ import org.mockito.stubbing.Answer;
import java.io.Serializable;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import static java.util.Arrays.asList;
import static org.mockito.internal.exceptions.Reporter.defaultAnswerDoesNotAcceptNullParameter;
import static org.mockito.internal.exceptions.Reporter.extraInterfacesAcceptsOnlyInterfaces;
import static org.mockito.internal.exceptions.Reporter.extraInterfacesDoesNotAcceptNullParameters;
import static org.mockito.internal.exceptions.Reporter.extraInterfacesRequiresAtLeastOneInterface;
+import static org.mockito.internal.exceptions.Reporter.invocationListenersRequiresAtLeastOneListener;
import static org.mockito.internal.exceptions.Reporter.methodDoesNotAcceptParameter;
-import static org.mockito.internal.exceptions.Reporter.requiresAtLeastOneListener;
import static org.mockito.internal.util.collections.Sets.newSet;
@SuppressWarnings("unchecked")
@@ -155,7 +154,7 @@ public class MockSettingsImpl<T> extends CreationSettings<T> implements MockSett
}
List<Object> resultArgs = new ArrayList<Object>(constructorArgs.length + 1);
resultArgs.add(outerClassInstance);
- resultArgs.addAll(asList(constructorArgs));
+ resultArgs.addAll(Arrays.asList(constructorArgs));
return resultArgs.toArray(new Object[constructorArgs.length + 1]);
}
@@ -174,23 +173,17 @@ public class MockSettingsImpl<T> extends CreationSettings<T> implements MockSett
@Override
public MockSettings invocationListeners(InvocationListener... listeners) {
+ if (listeners == null || listeners.length == 0) {
+ throw invocationListenersRequiresAtLeastOneListener();
+ }
addListeners(listeners, invocationListeners, "invocationListeners");
return this;
}
- @Override
- public MockSettings stubbingLookupListeners(StubbingLookupListener... listeners) {
- addListeners(listeners, stubbingLookupListeners, "stubbingLookupListeners");
- return this;
- }
-
- static <T> void addListeners(T[] listeners, List<T> container, String method) {
+ private static <T> void addListeners(T[] listeners, List<T> container, String method) {
if (listeners == null) {
throw methodDoesNotAcceptParameter(method, "null vararg array.");
}
- if (listeners.length == 0) {
- throw requiresAtLeastOneListener(method);
- }
for (T listener : listeners) {
if (listener == null) {
throw methodDoesNotAcceptParameter(method, "null listeners.");
@@ -214,8 +207,13 @@ public class MockSettingsImpl<T> extends CreationSettings<T> implements MockSett
return false;
}
+ @Override
+ public List<InvocationListener> getInvocationListeners() {
+ return this.invocationListeners;
+ }
+
public boolean hasInvocationListeners() {
- return !getInvocationListeners().isEmpty();
+ return !invocationListeners.isEmpty();
}
@Override
diff --git a/src/main/java/org/mockito/internal/creation/SuspendMethod.java b/src/main/java/org/mockito/internal/creation/SuspendMethod.java
index 42ceac6..018bc50 100644
--- a/src/main/java/org/mockito/internal/creation/SuspendMethod.java
+++ b/src/main/java/org/mockito/internal/creation/SuspendMethod.java
@@ -11,18 +11,12 @@ import java.util.Arrays;
* See <a href="https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md#continuation-passing-style">Design docs for details</a>.
*/
public class SuspendMethod {
- private static final String KOTLIN_EXPERIMENTAL_CONTINUATION = "kotlin.coroutines.experimental.Continuation";
- private static final String KOTLIN_CONTINUATION = "kotlin.coroutines.Continuation";
+ private static final String KOTLIN_CONTINUATION = "kotlin.coroutines.experimental.Continuation";
public static Class<?>[] trimSuspendParameterTypes(Class<?>[] parameterTypes) {
int n = parameterTypes.length;
- if (n > 0 && isContinuationType(parameterTypes[n - 1]))
+ if (n > 0 && parameterTypes[n - 1].getName().equals(KOTLIN_CONTINUATION))
return Arrays.copyOf(parameterTypes, n - 1);
return parameterTypes;
}
-
- private static boolean isContinuationType(Class<?> parameterType) {
- String name = parameterType.getName();
- return name.equals(KOTLIN_CONTINUATION) || name.equals(KOTLIN_EXPERIMENTAL_CONTINUATION);
- }
}
diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/InlineByteBuddyMockMaker.java b/src/main/java/org/mockito/internal/creation/bytebuddy/InlineByteBuddyMockMaker.java
index e99b915..42f10ce 100644
--- a/src/main/java/org/mockito/internal/creation/bytebuddy/InlineByteBuddyMockMaker.java
+++ b/src/main/java/org/mockito/internal/creation/bytebuddy/InlineByteBuddyMockMaker.java
@@ -14,7 +14,6 @@ import org.mockito.internal.util.Platform;
import org.mockito.internal.util.concurrent.WeakConcurrentMap;
import org.mockito.invocation.MockHandler;
import org.mockito.mock.MockCreationSettings;
-import org.mockito.plugins.InlineMockMaker;
import java.io.File;
import java.io.FileOutputStream;
@@ -26,8 +25,6 @@ import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
-import javax.tools.ToolProvider;
-
import static org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.EXCLUDES;
import static org.mockito.internal.util.StringUtil.join;
@@ -90,7 +87,7 @@ import static org.mockito.internal.util.StringUtil.join;
* support this feature.
*/
@Incubating
-public class InlineByteBuddyMockMaker implements ClassCreatingMockMaker, InlineMockMaker {
+public class InlineByteBuddyMockMaker implements ClassCreatingMockMaker {
private static final Instrumentation INSTRUMENTATION;
@@ -112,7 +109,7 @@ public class InlineByteBuddyMockMaker implements ClassCreatingMockMaker, InlineM
boot.deleteOnExit();
JarOutputStream outputStream = new JarOutputStream(new FileOutputStream(boot));
try {
- String source = "org/mockito/internal/creation/bytebuddy/inject/MockMethodDispatcher";
+ String source = "org/mockito/internal/creation/bytebuddy/MockMethodDispatcher";
InputStream inputStream = InlineByteBuddyMockMaker.class.getClassLoader().getResourceAsStream(source + ".raw");
if (inputStream == null) {
throw new IllegalStateException(join(
@@ -137,7 +134,13 @@ public class InlineByteBuddyMockMaker implements ClassCreatingMockMaker, InlineM
}
instrumentation.appendToBootstrapClassLoaderSearch(new JarFile(boot));
try {
- Class.forName("org.mockito.internal.creation.bytebuddy.inject.MockMethodDispatcher", false, null);
+ Class<?> dispatcher = Class.forName("org.mockito.internal.creation.bytebuddy.MockMethodDispatcher");
+ if (dispatcher.getClassLoader() != null) {
+ throw new IllegalStateException(join(
+ "The MockMethodDispatcher must not be loaded manually but must be injected into the bootstrap class loader.",
+ "",
+ "The dispatcher class was already loaded by: " + dispatcher.getClassLoader()));
+ }
} catch (ClassNotFoundException cnfe) {
throw new IllegalStateException(join(
"Mockito failed to inject the MockMethodDispatcher class into the bootstrap class loader",
@@ -167,7 +170,7 @@ public class InlineByteBuddyMockMaker implements ClassCreatingMockMaker, InlineM
if (INITIALIZATION_ERROR != null) {
throw new MockitoInitializationException(join(
"Could not initialize inline Byte Buddy mock maker. (This mock maker is not supported on Android.)",
- ToolProvider.getSystemJavaCompiler() == null ? "Are you running a JRE instead of a JDK? The inline mock maker needs to be run on a JDK.\n" : "",
+ "",
Platform.describe()), INITIALIZATION_ERROR);
}
bytecodeGenerator = new TypeCachingBytecodeGenerator(new InlineBytecodeGenerator(INSTRUMENTATION, mocks), true);
@@ -273,16 +276,6 @@ public class InlineByteBuddyMockMaker implements ClassCreatingMockMaker, InlineM
}
@Override
- public void clearMock(Object mock) {
- mocks.remove(mock);
- }
-
- @Override
- public void clearAllMocks() {
- mocks.clear();
- }
-
- @Override
public TypeMockability isTypeMockable(final Class<?> type) {
return new TypeMockability() {
@Override
diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/InlineBytecodeGenerator.java b/src/main/java/org/mockito/internal/creation/bytebuddy/InlineBytecodeGenerator.java
index e160e3c..64139c2 100644
--- a/src/main/java/org/mockito/internal/creation/bytebuddy/InlineBytecodeGenerator.java
+++ b/src/main/java/org/mockito/internal/creation/bytebuddy/InlineBytecodeGenerator.java
@@ -26,17 +26,17 @@ import net.bytebuddy.pool.TypePool;
import net.bytebuddy.utility.OpenedClassReader;
import net.bytebuddy.utility.RandomString;
import org.mockito.exceptions.base.MockitoException;
-import org.mockito.internal.creation.bytebuddy.inject.MockMethodDispatcher;
import org.mockito.internal.util.concurrent.WeakConcurrentMap;
import org.mockito.internal.util.concurrent.WeakConcurrentSet;
import org.mockito.mock.SerializableMode;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.Instrumentation;
-import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.security.ProtectionDomain;
-import java.util.*;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
import static net.bytebuddy.implementation.MethodDelegation.withDefaultConfiguration;
import static net.bytebuddy.implementation.bind.annotation.TargetMethodAnnotationDrivenBinder.ParameterBinder.ForFixedValue.OfConstant.of;
@@ -60,12 +60,14 @@ public class InlineBytecodeGenerator implements BytecodeGenerator, ClassFileTran
String.class));
private final Instrumentation instrumentation;
+
private final ByteBuddy byteBuddy;
+
private final WeakConcurrentSet<Class<?>> mocked;
+
private final BytecodeGenerator subclassEngine;
- private final AsmVisitorWrapper mockTransformer;
- private final Method getModule, canRead, redefineModule;
+ private final AsmVisitorWrapper mockTransformer;
private volatile Throwable lastException;
@@ -96,20 +98,6 @@ public class InlineBytecodeGenerator implements BytecodeGenerator, ClassFileTran
Advice.withCustomMapping()
.bind(MockMethodAdvice.Identifier.class, identifier)
.to(MockMethodAdvice.ForEquals.class));
- Method getModule, canRead, redefineModule;
- try {
- getModule = Class.class.getMethod("getModule");
- canRead = getModule.getReturnType().getMethod("canRead", getModule.getReturnType());
- redefineModule = Instrumentation.class.getMethod("redefineModule",
- getModule.getReturnType(), Set.class, Map.class, Map.class, Set.class, Map.class);
- } catch (Exception ignored) {
- getModule = null;
- canRead = null;
- redefineModule = null;
- }
- this.getModule = getModule;
- this.canRead = canRead;
- this.redefineModule = redefineModule;
MockMethodDispatcher.set(identifier, new MockMethodAdvice(mocks, identifier));
instrumentation.addTransformer(this, true);
}
@@ -170,7 +158,6 @@ public class InlineBytecodeGenerator implements BytecodeGenerator, ClassFileTran
} while (type != null);
if (!types.isEmpty()) {
try {
- assureCanReadMockito(types);
instrumentation.retransformClasses(types.toArray(new Class<?>[types.size()]));
Throwable throwable = lastException;
if (throwable != null) {
@@ -191,32 +178,6 @@ public class InlineBytecodeGenerator implements BytecodeGenerator, ClassFileTran
}
}
- private void assureCanReadMockito(Set<Class<?>> types) {
- if (redefineModule == null) {
- return;
- }
- Set<Object> modules = new HashSet<Object>();
- try {
- Object target = getModule.invoke(Class.forName("org.mockito.internal.creation.bytebuddy.inject.MockMethodDispatcher", false, null));
- for (Class<?> type : types) {
- Object module = getModule.invoke(type);
- if (!modules.contains(module) && !(Boolean) canRead.invoke(module, target)) {
- modules.add(module);
- }
- }
- for (Object module : modules) {
- redefineModule.invoke(instrumentation, module, Collections.singleton(target),
- Collections.emptyMap(), Collections.emptyMap(), Collections.emptySet(), Collections.emptyMap());
- }
- } catch (Exception e) {
- throw new IllegalStateException(join("Could not adjust module graph to make the mock instance dispatcher visible to some classes",
- "",
- "At least one of those modules: " + modules + " is not reading the unnamed module of the bootstrap loader",
- "Without such a read edge, the classes that are redefined to become mocks cannot access the mock dispatcher.",
- "To circumvent this, Mockito attempted to add a read edge to this module what failed for an unexpected reason"), e);
- }
- }
-
private <T> void checkSupportedCombination(boolean subclassingRequired, MockFeatures<T> features) {
if (subclassingRequired
&& !features.mockedType.isArray()
diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodAdvice.java b/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodAdvice.java
index 828b848..f39a1a2 100644
--- a/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodAdvice.java
+++ b/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodAdvice.java
@@ -12,7 +12,6 @@ import net.bytebuddy.implementation.bind.annotation.Argument;
import net.bytebuddy.implementation.bind.annotation.This;
import net.bytebuddy.implementation.bytecode.assign.Assigner;
import org.mockito.exceptions.base.MockitoException;
-import org.mockito.internal.creation.bytebuddy.inject.MockMethodDispatcher;
import org.mockito.internal.debugging.LocationImpl;
import org.mockito.internal.exceptions.stacktrace.ConditionalStackTraceFilter;
import org.mockito.internal.invocation.RealMethod;
@@ -36,7 +35,7 @@ import java.util.concurrent.Callable;
public class MockMethodAdvice extends MockMethodDispatcher {
- private final WeakConcurrentMap<Object, MockMethodInterceptor> interceptors;
+ final WeakConcurrentMap<Object, MockMethodInterceptor> interceptors;
private final String identifier;
diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodInterceptor.java b/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodInterceptor.java
index e57a82e..9066927 100644
--- a/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodInterceptor.java
+++ b/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodInterceptor.java
@@ -46,11 +46,13 @@ public class MockMethodInterceptor implements Serializable {
Method invokedMethod,
Object[] arguments,
RealMethod realMethod) throws Throwable {
- return doIntercept(mock,
- invokedMethod,
- arguments,
- realMethod,
- new LocationImpl());
+ return doIntercept(
+ mock,
+ invokedMethod,
+ arguments,
+ realMethod,
+ new LocationImpl()
+ );
}
Object doIntercept(Object mock,
@@ -106,11 +108,11 @@ public class MockMethodInterceptor implements Serializable {
return superCall.call();
}
return interceptor.doIntercept(
- mock,
- invokedMethod,
- arguments,
- new RealMethod.FromCallable(superCall)
- );
+ mock,
+ invokedMethod,
+ arguments,
+ new RealMethod.FromCallable(superCall)
+ );
}
@SuppressWarnings("unused")
@@ -124,11 +126,11 @@ public class MockMethodInterceptor implements Serializable {
return stubValue;
}
return interceptor.doIntercept(
- mock,
- invokedMethod,
- arguments,
- RealMethod.IsIllegal.INSTANCE
- );
+ mock,
+ invokedMethod,
+ arguments,
+ RealMethod.IsIllegal.INSTANCE
+ );
}
}
}
diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/ModuleHandler.java b/src/main/java/org/mockito/internal/creation/bytebuddy/ModuleHandler.java
deleted file mode 100644
index 5be0b95..0000000
--- a/src/main/java/org/mockito/internal/creation/bytebuddy/ModuleHandler.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Copyright (c) 2016 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
-package org.mockito.internal.creation.bytebuddy;
-
-import net.bytebuddy.ByteBuddy;
-import net.bytebuddy.description.modifier.Ownership;
-import net.bytebuddy.description.modifier.Visibility;
-import net.bytebuddy.dynamic.scaffold.subclass.ConstructorStrategy;
-import net.bytebuddy.implementation.Implementation;
-import net.bytebuddy.implementation.MethodCall;
-import net.bytebuddy.implementation.StubMethod;
-import org.mockito.codegen.InjectionBase;
-import org.mockito.exceptions.base.MockitoException;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.Random;
-
-import static net.bytebuddy.matcher.ElementMatchers.isTypeInitializer;
-import static org.mockito.internal.util.StringUtil.join;
-
-abstract class ModuleHandler {
-
- abstract boolean isOpened(Class<?> source, Class<?> target);
-
- abstract boolean canRead(Class<?> source, Class<?> target);
-
- abstract boolean isExported(Class<?> source);
-
- abstract boolean isExported(Class<?> source, Class<?> target);
-
- abstract Class<?> injectionBase(ClassLoader classLoader, String tyoeName);
-
- abstract void adjustModuleGraph(Class<?> source, Class<?> target, boolean export, boolean read);
-
- static ModuleHandler make(ByteBuddy byteBuddy, SubclassLoader loader, Random random) {
- try {
- return new ModuleSystemFound(
- byteBuddy, loader, random
- );
- } catch (Exception ignored) {
- return new NoModuleSystemFound();
- }
- }
-
- private static class ModuleSystemFound extends ModuleHandler {
-
- private final ByteBuddy byteBuddy;
- private final SubclassLoader loader;
- private final Random random;
-
- private final int injectonBaseSuffix;
-
- private final Method getModule, isOpen, isExported, isExportedUnqualified, canRead, addExports, addReads, addOpens, forName;
-
- private ModuleSystemFound(ByteBuddy byteBuddy, SubclassLoader loader, Random random) throws Exception {
- this.byteBuddy = byteBuddy;
- this.loader = loader;
- this.random = random;
- injectonBaseSuffix = Math.abs(random.nextInt());
- Class<?> moduleType = Class.forName("java.lang.Module");
- getModule = Class.class.getMethod("getModule");
- isOpen = moduleType.getMethod("isOpen", String.class, moduleType);
- isExported = moduleType.getMethod("isExported", String.class, moduleType);
- isExportedUnqualified = moduleType.getMethod("isExported", String.class);
- canRead = moduleType.getMethod("canRead", moduleType);
- addExports = moduleType.getMethod("addExports", String.class, moduleType);
- addReads = moduleType.getMethod("addReads", moduleType);
- addOpens = moduleType.getMethod("addOpens", String.class, moduleType);
- forName = Class.class.getMethod("forName", String.class);
- }
-
- @Override
- boolean isOpened(Class<?> source, Class<?> target) {
- if (source.getPackage() == null) {
- return true;
- }
- return (Boolean) invoke(isOpen, invoke(getModule, source), source.getPackage().getName(), invoke(getModule, target));
- }
-
- @Override
- boolean canRead(Class<?> source, Class<?> target) {
- return (Boolean) invoke(canRead, invoke(getModule, source), invoke(getModule, target));
- }
-
- @Override
- boolean isExported(Class<?> source) {
- if (source.getPackage() == null) {
- return true;
- }
- return (Boolean) invoke(isExportedUnqualified, invoke(getModule, source), source.getPackage().getName());
- }
-
- @Override
- boolean isExported(Class<?> source, Class<?> target) {
- if (source.getPackage() == null) {
- return true;
- }
- return (Boolean) invoke(isExported, invoke(getModule, source), source.getPackage().getName(), invoke(getModule, target));
- }
-
- @Override
- Class<?> injectionBase(ClassLoader classLoader, String typeName) {
- String packageName = typeName.substring(0, typeName.lastIndexOf('.'));
- if (classLoader == InjectionBase.class.getClassLoader() && InjectionBase.class.getPackage().getName().equals(packageName)) {
- return InjectionBase.class;
- } else {
- synchronized (this) {
- String name;
- int suffix = injectonBaseSuffix;
- do {
- name = packageName + "." + InjectionBase.class.getSimpleName() + "$" + suffix++;
- try {
- Class<?> type = Class.forName(name, false, classLoader);
- // The injected type must be defined in the class loader that is target of the injection. Otherwise,
- // the class's unnamed module would differ from the intended module. To avoid conflicts, we increment
- // the suffix until we hit a class with a known name and generate one if it does not exist.
- if (type.getClassLoader() == classLoader) {
- return type;
- }
- } catch (ClassNotFoundException ignored) {
- break;
- }
- } while (true);
- return byteBuddy.subclass(Object.class, ConstructorStrategy.Default.NO_CONSTRUCTORS)
- .name(name)
- .make()
- .load(classLoader, loader.resolveStrategy(InjectionBase.class, classLoader, false))
- .getLoaded();
- }
- }
- }
-
- @Override
- void adjustModuleGraph(Class<?> source, Class<?> target, boolean export, boolean read) {
- boolean needsExport = export && !isExported(source, target);
- boolean needsRead = read && !canRead(source, target);
- if (!needsExport && !needsRead) {
- return;
- }
- ClassLoader classLoader = source.getClassLoader();
- if (classLoader == null) {
- throw new MockitoException(join("Cannot adjust module graph for modules in the bootstrap loader",
- "",
- source + " is declared by the bootstrap loader and cannot be adjusted",
- "Requires package export to " + target + ": " + needsExport,
- "Requires adjusted reading of " + target + ": " + needsRead));
- }
- boolean targetVisible = classLoader == target.getClassLoader();
- while (!targetVisible && classLoader != null) {
- classLoader = classLoader.getParent();
- targetVisible = classLoader == target.getClassLoader();
- }
- MethodCall targetLookup;
- Implementation.Composable implementation;
- if (targetVisible) {
- targetLookup = MethodCall.invoke(getModule).onMethodCall(MethodCall.invoke(forName).with(target.getName()));
- implementation = StubMethod.INSTANCE;
- } else {
- Class<?> intermediate;
- Field field;
- try {
- intermediate = byteBuddy.subclass(Object.class, ConstructorStrategy.Default.NO_CONSTRUCTORS)
- .name(String.format("%s$%d", "org.mockito.codegen.MockitoTypeCarrier", Math.abs(random.nextInt())))
- .defineField("mockitoType", Class.class, Visibility.PUBLIC, Ownership.STATIC)
- .make()
- .load(source.getClassLoader(), loader.resolveStrategy(source, source.getClassLoader(), false))
- .getLoaded();
- field = intermediate.getField("mockitoType");
- field.set(null, target);
- } catch (Exception e) {
- throw new MockitoException(join("Could not create a carrier for making the Mockito type visible to " + source,
- "",
- "This is required to adjust the module graph to enable mock creation"), e);
- }
- targetLookup = MethodCall.invoke(getModule).onField(field);
- implementation = MethodCall.invoke(getModule).onMethodCall(MethodCall.invoke(forName).with(intermediate.getName()));
- }
- MethodCall sourceLookup = MethodCall.invoke(getModule).onMethodCall(MethodCall.invoke(forName).with(source.getName()));
- if (needsExport) {
- implementation = implementation.andThen(MethodCall.invoke(addExports)
- .onMethodCall(sourceLookup)
- .with(target.getPackage().getName())
- .withMethodCall(targetLookup));
- }
- if (needsRead) {
- implementation = implementation.andThen(MethodCall.invoke(addReads)
- .onMethodCall(sourceLookup)
- .withMethodCall(targetLookup));
- }
- try {
- Class.forName(byteBuddy.subclass(Object.class)
- .name(String.format("%s$%s$%d", source.getName(), "MockitoModuleProbe", Math.abs(random.nextInt())))
- .invokable(isTypeInitializer()).intercept(implementation)
- .make()
- .load(source.getClassLoader(), loader.resolveStrategy(source, source.getClassLoader(), false))
- .getLoaded()
- .getName(), true, source.getClassLoader());
- } catch (Exception e) {
- throw new MockitoException(join("Could not force module adjustment of the module of " + source,
- "",
- "This is required to adjust the module graph to enable mock creation"), e);
- }
- }
-
- private static Object invoke(Method method, Object target, Object... args) {
- try {
- return method.invoke(target, args);
- } catch (Exception e) {
- throw new MockitoException(join("Could not invoke " + method + " using reflection",
- "",
- "Mockito attempted to interact with the Java module system but an unexpected method behavior was encountered"), e);
- }
- }
- }
-
- private static class NoModuleSystemFound extends ModuleHandler {
-
- @Override
- boolean isOpened(Class<?> source, Class<?> target) {
- return true;
- }
-
- @Override
- boolean canRead(Class<?> source, Class<?> target) {
- return true;
- }
-
- @Override
- boolean isExported(Class<?> source) {
- return true;
- }
-
- @Override
- boolean isExported(Class<?> source, Class<?> target) {
- return true;
- }
-
- @Override
- Class<?> injectionBase(ClassLoader classLoader, String tyoeName) {
- return InjectionBase.class;
- }
-
- @Override
- void adjustModuleGraph(Class<?> source, Class<?> target, boolean export, boolean read) {
- // empty
- }
- }
-}
diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassBytecodeGenerator.java b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassBytecodeGenerator.java
index 093978d..b659c73 100644
--- a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassBytecodeGenerator.java
+++ b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassBytecodeGenerator.java
@@ -15,7 +15,6 @@ import net.bytebuddy.implementation.FieldAccessor;
import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.implementation.attribute.MethodAttributeAppender;
import net.bytebuddy.matcher.ElementMatcher;
-import org.mockito.codegen.InjectionBase;
import org.mockito.exceptions.base.MockitoException;
import org.mockito.internal.creation.bytebuddy.ByteBuddyCrossClassLoaderSerializationSupport.CrossClassLoaderSerializableMock;
import org.mockito.internal.creation.bytebuddy.MockMethodInterceptor.DispatcherDefaultingToRealMethod;
@@ -27,9 +26,6 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.LinkedList;
import java.util.Random;
import static java.lang.Thread.currentThread;
@@ -45,9 +41,10 @@ class SubclassBytecodeGenerator implements BytecodeGenerator {
private static final String CODEGEN_PACKAGE = "org.mockito.codegen.";
private final SubclassLoader loader;
- private final ModuleHandler handler;
+
private final ByteBuddy byteBuddy;
private final Random random;
+
private final Implementation readReplace;
private final ElementMatcher<? super MethodDescription> matcher;
@@ -74,128 +71,95 @@ class SubclassBytecodeGenerator implements BytecodeGenerator {
this.matcher = matcher;
byteBuddy = new ByteBuddy().with(TypeValidation.DISABLED);
random = new Random();
- handler = ModuleHandler.make(byteBuddy, loader, random);
}
@Override
public <T> Class<? extends T> mockClass(MockFeatures<T> features) {
- ClassLoader classLoader = new MultipleParentClassLoader.Builder()
- .appendMostSpecific(getAllTypes(features.mockedType))
- .appendMostSpecific(features.interfaces)
- .appendMostSpecific(currentThread().getContextClassLoader())
- .appendMostSpecific(MockAccess.class)
- .build();
-
- // If Mockito does not need to create a new class loader and if a mock is not based on a JDK type, we attempt
- // to define the mock class in the user runtime package to allow for mocking package private types and methods.
- // This also requires that we are able to access the package of the mocked class either by override or explicit
- // privilege given by the target package being opened to Mockito.
- boolean localMock = classLoader == features.mockedType.getClassLoader()
- && features.serializableMode != SerializableMode.ACROSS_CLASSLOADERS
- && !isComingFromJDK(features.mockedType)
- && (loader.isDisrespectingOpenness() || handler.isOpened(features.mockedType, MockAccess.class));
- String typeName;
- if (localMock || loader instanceof MultipleParentClassLoader && !isComingFromJDK(features.mockedType)) {
- typeName = features.mockedType.getName();
- } else {
- typeName = InjectionBase.class.getPackage().getName() + "." + features.mockedType.getSimpleName();
- }
- String name = String.format("%s$%s$%d", typeName, "MockitoMock", Math.abs(random.nextInt()));
-
- if (localMock) {
- handler.adjustModuleGraph(features.mockedType, MockAccess.class, false, true);
- for (Class<?> iFace : features.interfaces) {
- handler.adjustModuleGraph(iFace, features.mockedType, true, false);
- handler.adjustModuleGraph(features.mockedType, iFace, false, true);
- }
- } else {
- boolean exported = handler.isExported(features.mockedType);
- Iterator<Class<?>> it = features.interfaces.iterator();
- while (exported && it.hasNext()) {
- exported = handler.isExported(it.next());
- }
- // We check if all mocked types are exported without qualification to avoid generating a hook type.
- // unless this is necessary. We expect this to be the case for most mocked types what makes this a
- // worthy performance optimization.
- if (exported) {
- assertVisibility(features.mockedType);
- for (Class<?> iFace : features.interfaces) {
- assertVisibility(iFace);
- }
- } else {
- Class<?> hook = handler.injectionBase(classLoader, typeName);
- assertVisibility(features.mockedType);
- handler.adjustModuleGraph(features.mockedType, hook, true, false);
- for (Class<?> iFace : features.interfaces) {
- assertVisibility(iFace);
- handler.adjustModuleGraph(iFace, hook, true, false);
- }
- }
- }
-
- DynamicType.Builder<T> builder = byteBuddy.subclass(features.mockedType)
- .name(name)
- .ignoreAlso(isGroovyMethod())
- .annotateType(features.stripAnnotations
- ? new Annotation[0]
- : features.mockedType.getAnnotations())
- .implement(new ArrayList<Type>(features.interfaces))
- .method(matcher)
- .intercept(dispatcher)
- .transform(withModifiers(SynchronizationState.PLAIN))
- .attribute(features.stripAnnotations
- ? MethodAttributeAppender.NoOp.INSTANCE
- : INCLUDING_RECEIVER)
- .method(isHashCode())
- .intercept(hashCode)
- .method(isEquals())
- .intercept(equals)
- .serialVersionUid(42L)
- .defineField("mockitoInterceptor", MockMethodInterceptor.class, PRIVATE)
- .implement(MockAccess.class)
- .intercept(FieldAccessor.ofBeanProperty());
+ String name = nameFor(features.mockedType);
+ DynamicType.Builder<T> builder =
+ byteBuddy.subclass(features.mockedType)
+ .name(name)
+ .ignoreAlso(isGroovyMethod())
+ .annotateType(features.stripAnnotations
+ ? new Annotation[0]
+ : features.mockedType.getAnnotations())
+ .implement(new ArrayList<Type>(features.interfaces))
+ .method(matcher)
+ .intercept(dispatcher)
+ .transform(withModifiers(SynchronizationState.PLAIN))
+ .attribute(features.stripAnnotations
+ ? MethodAttributeAppender.NoOp.INSTANCE
+ : INCLUDING_RECEIVER)
+ .method(isHashCode())
+ .intercept(hashCode)
+ .method(isEquals())
+ .intercept(equals)
+ .serialVersionUid(42L)
+ .defineField("mockitoInterceptor", MockMethodInterceptor.class, PRIVATE)
+ .implement(MockAccess.class)
+ .intercept(FieldAccessor.ofBeanProperty());
if (features.serializableMode == SerializableMode.ACROSS_CLASSLOADERS) {
builder = builder.implement(CrossClassLoaderSerializableMock.class)
- .intercept(writeReplace);
+ .intercept(writeReplace);
}
if (readReplace != null) {
builder = builder.defineMethod("readObject", void.class, Visibility.PRIVATE)
- .withParameters(ObjectInputStream.class)
- .throwing(ClassNotFoundException.class, IOException.class)
- .intercept(readReplace);
+ .withParameters(ObjectInputStream.class)
+ .throwing(ClassNotFoundException.class, IOException.class)
+ .intercept(readReplace);
}
- if (name.startsWith(CODEGEN_PACKAGE) || classLoader instanceof MultipleParentClassLoader) {
+ ClassLoader classLoader = new MultipleParentClassLoader.Builder()
+ .append(features.mockedType)
+ .append(features.interfaces)
+ .append(currentThread().getContextClassLoader())
+ .append(MockAccess.class, DispatcherDefaultingToRealMethod.class)
+ .append(MockMethodInterceptor.class,
+ MockMethodInterceptor.ForHashCode.class,
+ MockMethodInterceptor.ForEquals.class).build(MockMethodInterceptor.class.getClassLoader());
+ if (classLoader != features.mockedType.getClassLoader()) {
+ assertVisibility(features.mockedType);
+ for (Class<?> iFace : features.interfaces) {
+ assertVisibility(iFace);
+ }
builder = builder.ignoreAlso(isPackagePrivate()
.or(returns(isPackagePrivate()))
.or(hasParameters(whereAny(hasType(isPackagePrivate())))));
}
return builder.make()
- .load(classLoader, loader.resolveStrategy(features.mockedType, classLoader, localMock))
- .getLoaded();
- }
-
- private <T> Collection<Class<? super T>> getAllTypes(Class<T> type) {
- Collection<Class<? super T>> supertypes = new LinkedList<Class<? super T>>();
- supertypes.add(type);
- Class<? super T> superType = type;
- while (superType != null) {
- supertypes.add(superType);
- superType = superType.getSuperclass();
- }
- return supertypes;
+ .load(classLoader, loader.resolveStrategy(features.mockedType, classLoader, name.startsWith(CODEGEN_PACKAGE)))
+ .getLoaded();
}
private static ElementMatcher<MethodDescription> isGroovyMethod() {
return isDeclaredBy(named("groovy.lang.GroovyObjectSupport"));
}
+ // TODO inspect naming strategy (for OSGI, signed package, java.* (and bootstrap classes), etc...)
+ private String nameFor(Class<?> type) {
+ String typeName = type.getName();
+ if (isComingFromJDK(type)
+ || isComingFromSignedJar(type)
+ || isComingFromSealedPackage(type)) {
+ typeName = CODEGEN_PACKAGE + type.getSimpleName();
+ }
+ return String.format("%s$%s$%d", typeName, "MockitoMock", Math.abs(random.nextInt()));
+ }
+
private boolean isComingFromJDK(Class<?> type) {
// Comes from the manifest entry :
// Implementation-Title: Java Runtime Environment
// This entry is not necessarily present in every jar of the JDK
return type.getPackage() != null && "Java Runtime Environment".equalsIgnoreCase(type.getPackage().getImplementationTitle())
- || type.getName().startsWith("java.")
- || type.getName().startsWith("javax.");
+ || type.getName().startsWith("java.")
+ || type.getName().startsWith("javax.");
+ }
+
+ private boolean isComingFromSealedPackage(Class<?> type) {
+ return type.getPackage() != null && type.getPackage().isSealed();
+ }
+
+ private boolean isComingFromSignedJar(Class<?> type) {
+ return type.getSigners() != null;
}
private static void assertVisibility(Class<?> type) {
diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassInjectionLoader.java b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassInjectionLoader.java
index 89b0a30..454dd8e 100644
--- a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassInjectionLoader.java
+++ b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassInjectionLoader.java
@@ -25,7 +25,7 @@ class SubclassInjectionLoader implements SubclassLoader {
private final SubclassLoader loader;
SubclassInjectionLoader() {
- if (!Boolean.getBoolean("org.mockito.internal.noUnsafeInjection") && ClassInjector.UsingReflection.isAvailable()) {
+ if (!Boolean.getBoolean("org.mockito.internal.simulateJava11") && ClassInjector.UsingReflection.isAvailable()) {
this.loader = new WithReflection();
} else if (ClassInjector.UsingLookup.isAvailable()) {
this.loader = tryLookup();
@@ -49,13 +49,8 @@ class SubclassInjectionLoader implements SubclassLoader {
private static class WithReflection implements SubclassLoader {
@Override
- public boolean isDisrespectingOpenness() {
- return true;
- }
-
- @Override
- public ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean localMock) {
- return ClassLoadingStrategy.Default.INJECTION.with(localMock ? mockedType.getProtectionDomain() : InjectionBase.class.getProtectionDomain());
+ public ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean codegen) {
+ return ClassLoadingStrategy.Default.INJECTION.with(codegen ? InjectionBase.class.getProtectionDomain() : mockedType.getProtectionDomain());
}
}
@@ -74,13 +69,12 @@ class SubclassInjectionLoader implements SubclassLoader {
}
@Override
- public boolean isDisrespectingOpenness() {
- return false;
- }
-
- @Override
- public ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean localMock) {
- if (localMock) {
+ public ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean codegen) {
+ if (codegen) {
+ return ClassLoadingStrategy.UsingLookup.of(codegenLookup);
+ } else if (classLoader != mockedType.getClassLoader()) {
+ return ClassLoadingStrategy.Default.WRAPPER.with(mockedType.getProtectionDomain());
+ } else {
try {
Object privateLookup;
try {
@@ -102,21 +96,12 @@ class SubclassInjectionLoader implements SubclassLoader {
exception
));
}
- } else if (classLoader == InjectionBase.class.getClassLoader()) {
- return ClassLoadingStrategy.UsingLookup.of(codegenLookup);
- } else {
- return ClassLoadingStrategy.Default.WRAPPER.with(mockedType.getProtectionDomain());
}
}
}
@Override
- public boolean isDisrespectingOpenness() {
- return loader.isDisrespectingOpenness();
- }
-
- @Override
- public ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean localMock) {
- return loader.resolveStrategy(mockedType, classLoader, localMock);
+ public ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean codegen) {
+ return loader.resolveStrategy(mockedType, classLoader, codegen);
}
}
diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassLoader.java b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassLoader.java
index 011504e..194c282 100644
--- a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassLoader.java
+++ b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassLoader.java
@@ -12,19 +12,12 @@ import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
public interface SubclassLoader {
/**
- * Checks if this loader does not require a module to be open.
- *
- * @return {@code true} if this loader is not constraint to a target module being opened for loading a class.
- */
- boolean isDisrespectingOpenness();
-
- /**
* Resolves a class loading strategy.
*
* @param mockedType The type being mocked.
* @param classLoader The class loader being used.
- * @param localMock {@code true} if the mock is loaded within the runtime package of the mocked type.
+ * @param codegen {@code true} if the mock is loaded in the {@code org.mockito.codegen} package.
* @return An appropriate class loading strategy.
*/
- ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean localMock);
+ ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean codegen);
}
diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/inject/MockMethodDispatcher.java b/src/main/java/org/mockito/internal/creation/bytebuddy/inject/MockMethodDispatcher.java
deleted file mode 100644
index 12e30db..0000000
--- a/src/main/java/org/mockito/internal/creation/bytebuddy/inject/MockMethodDispatcher.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2016 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
-package org.mockito.internal.creation.bytebuddy.inject;
-
-import java.lang.reflect.Method;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-public abstract class MockMethodDispatcher {
-
- private static final ConcurrentMap<String, MockMethodDispatcher> INSTANCE = new ConcurrentHashMap<String, MockMethodDispatcher>();
-
- public static MockMethodDispatcher get(String identifier, Object mock) {
- if (mock == INSTANCE) { // Avoid endless loop if ConcurrentHashMap was redefined to check for being a mock.
- return null;
- } else {
- return INSTANCE.get(identifier);
- }
- }
-
- public static void set(String identifier, MockMethodDispatcher dispatcher) {
- INSTANCE.putIfAbsent(identifier, dispatcher);
- }
-
- public abstract Callable<?> handle(Object instance, Method origin, Object[] arguments) throws Throwable;
-
- public abstract boolean isMock(Object instance);
-
- public abstract boolean isMocked(Object instance);
-
- public abstract boolean isOverridden(Object instance, Method origin);
-}
diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/inject/package-info.java b/src/main/java/org/mockito/internal/creation/bytebuddy/inject/package-info.java
deleted file mode 100644
index 5abed05..0000000
--- a/src/main/java/org/mockito/internal/creation/bytebuddy/inject/package-info.java
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
-
-/**
- * Internal classes, not to be used by clients. Intended for injection into the bootstrap class loader.
- *
- * Subject to change at any time without notice.
- */
-package org.mockito.internal.creation.bytebuddy.inject;
diff --git a/src/main/java/org/mockito/internal/creation/settings/CreationSettings.java b/src/main/java/org/mockito/internal/creation/settings/CreationSettings.java
index 3b45592..03afd80 100644
--- a/src/main/java/org/mockito/internal/creation/settings/CreationSettings.java
+++ b/src/main/java/org/mockito/internal/creation/settings/CreationSettings.java
@@ -4,8 +4,8 @@
*/
package org.mockito.internal.creation.settings;
+import org.mockito.internal.listeners.StubbingLookupListener;
import org.mockito.listeners.InvocationListener;
-import org.mockito.listeners.StubbingLookupListener;
import org.mockito.listeners.VerificationStartedListener;
import org.mockito.mock.MockCreationSettings;
import org.mockito.mock.MockName;
@@ -18,7 +18,6 @@ import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
-import java.util.concurrent.CopyOnWriteArrayList;
public class CreationSettings<T> implements MockCreationSettings<T>, Serializable {
private static final long serialVersionUID = -6789800638070123629L;
@@ -31,11 +30,7 @@ public class CreationSettings<T> implements MockCreationSettings<T>, Serializabl
protected MockName mockName;
protected SerializableMode serializableMode = SerializableMode.NONE;
protected List<InvocationListener> invocationListeners = new ArrayList<InvocationListener>();
-
- //Other listeners in this class may also need concurrency-safe implementation. However, no issue was reported about it.
- // If we do it, we need to understand usage patterns and choose the right concurrent implementation.
- protected List<StubbingLookupListener> stubbingLookupListeners = new CopyOnWriteArrayList<StubbingLookupListener>();
-
+ protected final List<StubbingLookupListener> stubbingLookupListeners = new ArrayList<StubbingLookupListener>();
protected List<VerificationStartedListener> verificationStartedListeners = new LinkedList<VerificationStartedListener>();
protected boolean stubOnly;
protected boolean stripAnnotations;
@@ -48,7 +43,6 @@ public class CreationSettings<T> implements MockCreationSettings<T>, Serializabl
@SuppressWarnings("unchecked")
public CreationSettings(CreationSettings copy) {
- //TODO can we have a reflection test here? We had a couple of bugs here in the past.
this.typeToMock = copy.typeToMock;
this.extraInterfaces = copy.extraInterfaces;
this.name = copy.name;
@@ -57,14 +51,12 @@ public class CreationSettings<T> implements MockCreationSettings<T>, Serializabl
this.mockName = copy.mockName;
this.serializableMode = copy.serializableMode;
this.invocationListeners = copy.invocationListeners;
- this.stubbingLookupListeners = copy.stubbingLookupListeners;
this.verificationStartedListeners = copy.verificationStartedListeners;
this.stubOnly = copy.stubOnly;
this.useConstructor = copy.isUsingConstructor();
this.outerClassInstance = copy.getOuterClassInstance();
this.constructorArgs = copy.getConstructorArgs();
this.lenient = copy.lenient;
- this.stripAnnotations = copy.stripAnnotations;
}
@Override
diff --git a/src/main/java/org/mockito/internal/debugging/LocationImpl.java b/src/main/java/org/mockito/internal/debugging/LocationImpl.java
index f1d14a6..8561b62 100644
--- a/src/main/java/org/mockito/internal/debugging/LocationImpl.java
+++ b/src/main/java/org/mockito/internal/debugging/LocationImpl.java
@@ -16,7 +16,6 @@ public class LocationImpl implements Location, Serializable {
private final Throwable stackTraceHolder;
private final StackTraceFilter stackTraceFilter;
- private final String sourceFile;
public LocationImpl() {
this(defaultStackTraceFilter);
@@ -33,13 +32,6 @@ public class LocationImpl implements Location, Serializable {
private LocationImpl(StackTraceFilter stackTraceFilter, Throwable stackTraceHolder) {
this.stackTraceFilter = stackTraceFilter;
this.stackTraceHolder = stackTraceHolder;
- if (stackTraceHolder.getStackTrace() == null || stackTraceHolder.getStackTrace().length == 0) {
- //there are corner cases where exception can have a null or empty stack trace
- //for example, a custom exception can override getStackTrace() method
- this.sourceFile = "<unknown source file>";
- } else {
- this.sourceFile = stackTraceFilter.findSourceFile(stackTraceHolder.getStackTrace(), "<unknown source file>");
- }
}
@Override
@@ -51,9 +43,4 @@ public class LocationImpl implements Location, Serializable {
}
return "-> at " + filtered[0].toString();
}
-
- @Override
- public String getSourceFile() {
- return sourceFile;
- }
}
diff --git a/src/main/java/org/mockito/internal/exceptions/Reporter.java b/src/main/java/org/mockito/internal/exceptions/Reporter.java
index 1b68fbb..2bc4445 100644
--- a/src/main/java/org/mockito/internal/exceptions/Reporter.java
+++ b/src/main/java/org/mockito/internal/exceptions/Reporter.java
@@ -26,6 +26,7 @@ import org.mockito.invocation.Invocation;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.invocation.Location;
import org.mockito.listeners.InvocationListener;
+import org.mockito.mock.MockName;
import org.mockito.mock.SerializableMode;
import java.lang.reflect.Field;
@@ -83,7 +84,7 @@ public class Reporter {
"Hints:",
" 1. missing thenReturn()",
" 2. you are trying to stub a final method, which is not supported",
- " 3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction is completed",
+ " 3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed",
""
));
}
@@ -276,10 +277,10 @@ public class Reporter {
));
}
- public static MockitoException stubPassedToVerify(Object mock) {
+ public static MockitoException stubPassedToVerify() {
return new CannotVerifyStubOnlyMock(join(
- "Argument \"" + MockUtil.getMockName(mock) + "\" passed to verify is a stubOnly() mock which cannot be verified.",
- "If you intend to verify invocations on this mock, don't use stubOnly() in its MockSettings."
+ "Argument passed to verify() is a stubOnly() mock, not a full blown mock!",
+ "If you intend to verify invocations on a mock, don't use stubOnly() in its MockSettings."
));
}
@@ -436,7 +437,7 @@ public class Reporter {
return new NoInteractionsWanted(join(
"No interactions wanted here:",
new LocationImpl(),
- "But found this interaction on mock '" + MockUtil.getMockName(undesired.getMock()) + "':",
+ "But found this interaction on mock '" + safelyGetMockName(undesired.getMock()) + "':",
undesired.getLocation(),
scenario
));
@@ -446,7 +447,7 @@ public class Reporter {
return new VerificationInOrderFailure(join(
"No interactions wanted here:",
new LocationImpl(),
- "But found this interaction on mock '" + MockUtil.getMockName(undesired.getMock()) + "':",
+ "But found this interaction on mock '" + safelyGetMockName(undesired.getMock()) + "':",
undesired.getLocation()
));
}
@@ -512,7 +513,7 @@ public class Reporter {
actualType + " cannot be returned by " + methodName + "()",
methodName + "() should return " + expectedType,
"",
- "The default answer of " + MockUtil.getMockName(mock) + " that was configured on the mock is probably incorrectly implemented.",
+ "The default answer of " + safelyGetMockName(mock) + " that was configured on the mock is probably incorrectly implemented.",
""
));
}
@@ -672,7 +673,7 @@ public class Reporter {
}
public static MockitoException fieldInitialisationThrewException(Field field, Throwable details) {
- return new InjectMocksException(join(
+ return new MockitoException(join(
"Cannot instantiate @InjectMocks field named '" + field.getName() + "' of type '" + field.getType() + "'.",
"You haven't provided the instance at field declaration so I tried to construct the instance.",
"However the constructor or the initialization block threw an exception : " + details.getMessage(),
@@ -684,8 +685,8 @@ public class Reporter {
return new MockitoException(method + "() does not accept " + parameter + " See the Javadoc.");
}
- public static MockitoException requiresAtLeastOneListener(String method) {
- return new MockitoException(method + "() requires at least one listener");
+ public static MockitoException invocationListenersRequiresAtLeastOneListener() {
+ return new MockitoException("invocationListeners() requires at least one listener");
}
public static MockitoException invocationListenerThrewException(InvocationListener listener, Throwable listenerThrowable) {
@@ -696,7 +697,7 @@ public class Reporter {
public static MockitoException cannotInjectDependency(Field field, Object matchingMock, Exception details) {
return new MockitoException(join(
- "Mockito couldn't inject mock dependency '" + MockUtil.getMockName(matchingMock) + "' on field ",
+ "Mockito couldn't inject mock dependency '" + safelyGetMockName(matchingMock) + "' on field ",
"'" + field + "'",
"whose type '" + field.getDeclaringClass().getCanonicalName() + "' was annotated by @InjectMocks in your test.",
"Also I failed because: " + exceptionCauseMessageIfAvailable(details),
@@ -739,7 +740,7 @@ public class Reporter {
public static MockitoException invalidArgumentPositionRangeAtInvocationTime(InvocationOnMock invocation, boolean willReturnLastParameter, int argumentIndex) {
return new MockitoException(join(
"Invalid argument index for the current invocation of method : ",
- " -> " + MockUtil.getMockName(invocation.getMock()) + "." + invocation.getMethod().getName() + "()",
+ " -> " + safelyGetMockName(invocation.getMock()) + "." + invocation.getMethod().getName() + "()",
"",
(willReturnLastParameter ?
"Last parameter wanted" :
@@ -773,7 +774,7 @@ public class Reporter {
return new WrongTypeOfReturnValue(join(
"The argument of type '" + actualType.getSimpleName() + "' cannot be returned because the following ",
"method should return the type '" + expectedType + "'",
- " -> " + MockUtil.getMockName(invocation.getMock()) + "." + invocation.getMethod().getName() + "()",
+ " -> " + safelyGetMockName(invocation.getMock()) + "." + invocation.getMethod().getName() + "()",
"",
"The reason for this error can be :",
"1. The wanted argument position is incorrect.",
@@ -810,7 +811,7 @@ public class Reporter {
public static MockitoException delegatedMethodHasWrongReturnType(Method mockMethod, Method delegateMethod, Object mock, Object delegate) {
return new MockitoException(join(
"Methods called on delegated instance must have compatible return types with the mock.",
- "When calling: " + mockMethod + " on mock: " + MockUtil.getMockName(mock),
+ "When calling: " + mockMethod + " on mock: " + safelyGetMockName(mock),
"return type should be: " + mockMethod.getReturnType().getSimpleName() + ", but was: " + delegateMethod.getReturnType().getSimpleName(),
"Check that the instance passed to delegatesTo() is of the correct type or contains compatible methods",
"(delegate instance had type: " + delegate.getClass().getSimpleName() + ")"
@@ -820,7 +821,7 @@ public class Reporter {
public static MockitoException delegatedMethodDoesNotExistOnDelegate(Method mockMethod, Object mock, Object delegate) {
return new MockitoException(join(
"Methods called on mock must exist in delegated instance.",
- "When calling: " + mockMethod + " on mock: " + MockUtil.getMockName(mock),
+ "When calling: " + mockMethod + " on mock: " + safelyGetMockName(mock),
"no such method was found.",
"Check that the instance passed to delegatesTo() is of the correct type or contains compatible methods",
"(delegate instance had type: " + delegate.getClass().getSimpleName() + ")"
@@ -848,6 +849,10 @@ public class Reporter {
"This may happen with doThrow(Class)|thenThrow(Class) family of methods if passing null parameter."));
}
+ private static MockName safelyGetMockName(Object mock) {
+ return MockUtil.getMockName(mock);
+ }
+
public static UnnecessaryStubbingException formatUnncessaryStubbingException(Class<?> testClass, Collection<Invocation> unnecessaryStubbings) {
StringBuilder stubbings = new StringBuilder();
int count = 1;
diff --git a/src/main/java/org/mockito/internal/exceptions/stacktrace/StackTraceFilter.java b/src/main/java/org/mockito/internal/exceptions/stacktrace/StackTraceFilter.java
index bf11d4c..e8b0cb0 100644
--- a/src/main/java/org/mockito/internal/exceptions/stacktrace/StackTraceFilter.java
+++ b/src/main/java/org/mockito/internal/exceptions/stacktrace/StackTraceFilter.java
@@ -37,17 +37,4 @@ public class StackTraceFilter implements Serializable {
StackTraceElement[] result = new StackTraceElement[filtered.size()];
return filtered.toArray(result);
}
-
- /**
- * Finds the source file of the target stack trace.
- * Returns the default value if source file cannot be found.
- */
- public String findSourceFile(StackTraceElement[] target, String defaultValue) {
- for (StackTraceElement e : target) {
- if (CLEANER.isIn(e)) {
- return e.getFileName();
- }
- }
- return defaultValue;
- }
}
diff --git a/src/main/java/org/mockito/internal/framework/DefaultMockitoFramework.java b/src/main/java/org/mockito/internal/framework/DefaultMockitoFramework.java
index d92fc28..69a733c 100644
--- a/src/main/java/org/mockito/internal/framework/DefaultMockitoFramework.java
+++ b/src/main/java/org/mockito/internal/framework/DefaultMockitoFramework.java
@@ -10,8 +10,6 @@ import org.mockito.internal.invocation.DefaultInvocationFactory;
import org.mockito.internal.util.Checks;
import org.mockito.invocation.InvocationFactory;
import org.mockito.listeners.MockitoListener;
-import org.mockito.plugins.InlineMockMaker;
-import org.mockito.plugins.MockMaker;
import org.mockito.plugins.MockitoPlugins;
import static org.mockito.internal.progress.ThreadSafeMockingProgress.mockingProgress;
@@ -39,25 +37,4 @@ public class DefaultMockitoFramework implements MockitoFramework {
public InvocationFactory getInvocationFactory() {
return new DefaultInvocationFactory();
}
-
- private InlineMockMaker getInlineMockMaker() {
- MockMaker mockMaker = Plugins.getMockMaker();
- return (mockMaker instanceof InlineMockMaker) ? (InlineMockMaker) mockMaker : null;
- }
-
- @Override
- public void clearInlineMocks() {
- InlineMockMaker mockMaker = getInlineMockMaker();
- if (mockMaker != null) {
- mockMaker.clearAllMocks();
- }
- }
-
- @Override
- public void clearInlineMock(Object mock) {
- InlineMockMaker mockMaker = getInlineMockMaker();
- if (mockMaker != null) {
- mockMaker.clearMock(mock);
- }
- }
}
diff --git a/src/main/java/org/mockito/internal/framework/DefaultMockitoSession.java b/src/main/java/org/mockito/internal/framework/DefaultMockitoSession.java
index 6483a1c..c900bf7 100644
--- a/src/main/java/org/mockito/internal/framework/DefaultMockitoSession.java
+++ b/src/main/java/org/mockito/internal/framework/DefaultMockitoSession.java
@@ -11,17 +11,19 @@ import org.mockito.exceptions.misusing.RedundantListenerException;
import org.mockito.internal.exceptions.Reporter;
import org.mockito.internal.junit.TestFinishedEvent;
import org.mockito.internal.junit.UniversalTestListener;
-import org.mockito.plugins.MockitoLogger;
+import org.mockito.internal.util.MockitoLogger;
import org.mockito.quality.Strictness;
import java.util.List;
public class DefaultMockitoSession implements MockitoSession {
+ private final List<Object> testClassInstances;
private final String name;
private final UniversalTestListener listener;
public DefaultMockitoSession(List<Object> testClassInstances, String name, Strictness strictness, MockitoLogger logger) {
+ this.testClassInstances = testClassInstances;
this.name = name;
listener = new UniversalTestListener(strictness, logger);
try {
@@ -30,14 +32,8 @@ public class DefaultMockitoSession implements MockitoSession {
} catch (RedundantListenerException e) {
Reporter.unfinishedMockingSession();
}
- try {
- for (Object testClassInstance : testClassInstances) {
- MockitoAnnotations.initMocks(testClassInstance);
- }
- } catch (RuntimeException e) {
- //clean up in case 'initMocks' fails
- listener.setListenerDirty();
- throw e;
+ for (Object testClassInstance : testClassInstances) {
+ MockitoAnnotations.initMocks(testClassInstance);
}
}
diff --git a/src/main/java/org/mockito/internal/invocation/InterceptedInvocation.java b/src/main/java/org/mockito/internal/invocation/InterceptedInvocation.java
index ec1fcba..b9cf072 100644
--- a/src/main/java/org/mockito/internal/invocation/InterceptedInvocation.java
+++ b/src/main/java/org/mockito/internal/invocation/InterceptedInvocation.java
@@ -4,7 +4,6 @@
*/
package org.mockito.internal.invocation;
-import org.mockito.ArgumentMatcher;
import org.mockito.internal.invocation.mockref.MockReference;
import org.mockito.internal.exceptions.VerificationAwareInvocation;
import org.mockito.internal.reporting.PrintSettings;
@@ -14,10 +13,8 @@ import org.mockito.invocation.StubInfo;
import java.lang.reflect.Method;
import java.util.Arrays;
-import java.util.List;
import static org.mockito.internal.exceptions.Reporter.cannotCallAbstractRealMethod;
-import static org.mockito.internal.invocation.ArgumentsProcessor.argumentsToMatchers;
public class InterceptedInvocation implements Invocation, VerificationAwareInvocation {
@@ -122,28 +119,6 @@ public class InterceptedInvocation implements Invocation, VerificationAwareInvoc
return (T) arguments[index];
}
- public MockReference<Object> getMockRef() {
- return mockRef;
- }
-
- public MockitoMethod getMockitoMethod() {
- return mockitoMethod;
- }
-
- public RealMethod getRealMethod() {
- return realMethod;
- }
-
- @Override
- public List<ArgumentMatcher> getArgumentsAsMatchers() {
- return argumentsToMatchers(getArguments());
- }
-
- @Override
- public <T> T getArgument(int index, Class<T> clazz) {
- return clazz.cast(arguments[index]);
- }
-
@Override
public Object callRealMethod() throws Throwable {
if (!realMethod.isInvokable()) {
@@ -174,7 +149,7 @@ public class InterceptedInvocation implements Invocation, VerificationAwareInvoc
}
public String toString() {
- return new PrintSettings().print(getArgumentsAsMatchers(), this);
+ return new PrintSettings().print(ArgumentsProcessor.argumentsToMatchers(getArguments()), this);
}
public final static RealMethod NO_OP = new RealMethod() {
diff --git a/src/main/java/org/mockito/internal/invocation/InvocationMatcher.java b/src/main/java/org/mockito/internal/invocation/InvocationMatcher.java
index bc14300..83a28ff 100644
--- a/src/main/java/org/mockito/internal/invocation/InvocationMatcher.java
+++ b/src/main/java/org/mockito/internal/invocation/InvocationMatcher.java
@@ -5,6 +5,7 @@
package org.mockito.internal.invocation;
+import static org.mockito.internal.invocation.ArgumentsProcessor.argumentsToMatchers;
import static org.mockito.internal.invocation.MatcherApplicationStrategy.getMatcherApplicationStrategyFor;
import static org.mockito.internal.invocation.TypeSafeMatching.matchesTypeSafe;
@@ -35,7 +36,7 @@ public class InvocationMatcher implements MatchableInvocation, DescribedInvocati
public InvocationMatcher(Invocation invocation, List<ArgumentMatcher> matchers) {
this.invocation = invocation;
if (matchers.isEmpty()) {
- this.matchers = (List) invocation.getArgumentsAsMatchers();
+ this.matchers = (List) argumentsToMatchers(invocation.getArguments());
} else {
this.matchers = (List) matchers;
}
diff --git a/src/main/java/org/mockito/internal/junit/DefaultStubbingLookupListener.java b/src/main/java/org/mockito/internal/junit/DefaultStubbingLookupListener.java
index b5d2022..4885d63 100644
--- a/src/main/java/org/mockito/internal/junit/DefaultStubbingLookupListener.java
+++ b/src/main/java/org/mockito/internal/junit/DefaultStubbingLookupListener.java
@@ -5,14 +5,13 @@
package org.mockito.internal.junit;
import org.mockito.internal.exceptions.Reporter;
+import org.mockito.internal.listeners.StubbingLookupEvent;
+import org.mockito.internal.listeners.StubbingLookupListener;
import org.mockito.internal.stubbing.UnusedStubbingReporting;
import org.mockito.invocation.Invocation;
-import org.mockito.listeners.StubbingLookupEvent;
-import org.mockito.listeners.StubbingLookupListener;
import org.mockito.quality.Strictness;
import org.mockito.stubbing.Stubbing;
-import java.io.Serializable;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
@@ -23,9 +22,7 @@ import static org.mockito.internal.stubbing.StrictnessSelector.determineStrictne
* Default implementation of stubbing lookup listener.
* Fails early if stub called with unexpected arguments, but only if current strictness is set to STRICT_STUBS.
*/
-class DefaultStubbingLookupListener implements StubbingLookupListener, Serializable {
-
- private static final long serialVersionUID = -6789800638070123629L;
+class DefaultStubbingLookupListener implements StubbingLookupListener {
private Strictness currentStrictness;
private boolean mismatchesReported;
@@ -60,11 +57,8 @@ class DefaultStubbingLookupListener implements StubbingLookupListener, Serializa
List<Invocation> matchingStubbings = new LinkedList<Invocation>();
for (Stubbing s : stubbings) {
if (UnusedStubbingReporting.shouldBeReported(s)
- && s.getInvocation().getMethod().getName().equals(invocation.getMethod().getName())
- //If stubbing and invocation are in the same source file we assume they are in the test code,
- // and we don't flag it as mismatch:
- && !s.getInvocation().getLocation().getSourceFile().equals(invocation.getLocation().getSourceFile())) {
- matchingStubbings.add(s.getInvocation());
+ && s.getInvocation().getMethod().getName().equals(invocation.getMethod().getName())) {
+ matchingStubbings.add(s.getInvocation());
}
}
return matchingStubbings;
diff --git a/src/main/java/org/mockito/internal/junit/ExceptionFactory.java b/src/main/java/org/mockito/internal/junit/ExceptionFactory.java
index 5db296e..3664aea 100644
--- a/src/main/java/org/mockito/internal/junit/ExceptionFactory.java
+++ b/src/main/java/org/mockito/internal/junit/ExceptionFactory.java
@@ -4,58 +4,49 @@
*/
package org.mockito.internal.junit;
+import junit.framework.ComparisonFailure;
import org.mockito.exceptions.verification.ArgumentsAreDifferent;
public class ExceptionFactory {
+ private final static boolean hasJUnit = canLoadJunitClass();
+
private ExceptionFactory() {
}
- private static interface ExceptionFactoryImpl {
- AssertionError create(String message, String wanted, String actual);
+ /**
+ * If JUnit is used, an AssertionError is returned that extends from JUnit {@link ComparisonFailure} and hence provide a better IDE support as the comparison result is comparable
+ */
+ public static AssertionError createArgumentsAreDifferentException(String message, String wanted, String actual) {
+ if (hasJUnit) {
+ return createJUnitArgumentsAreDifferent(message, wanted, actual);
+ }
+ return new ArgumentsAreDifferent(message);
}
- private final static ExceptionFactoryImpl factory;
-
- static {
- ExceptionFactoryImpl theFactory = null;
+ private static AssertionError createJUnitArgumentsAreDifferent(String message, String wanted, String actual) {
+ return JUnitArgsAreDifferent.create(message, wanted, actual);
+ }
+ private static boolean canLoadJunitClass() {
try {
- theFactory = new ExceptionFactoryImpl() {
- @Override
- public AssertionError create(String message, String wanted, String actual) {
- return new org.mockito.exceptions.verification.opentest4j.ArgumentsAreDifferent(message, wanted, actual);
- }
- };
- } catch (Throwable onlyIfOpenTestIsNotAvailable) {
- try {
- theFactory = new ExceptionFactoryImpl() {
- @Override
- public AssertionError create(String message, String wanted, String actual) {
- return new org.mockito.exceptions.verification.junit.ArgumentsAreDifferent(message, wanted, actual);
- }
- };
- } catch (Throwable onlyIfJUnitIsNotAvailable) {
- }
+ JUnitArgsAreDifferent.create("message", "wanted", "actual");
+ } catch (NoClassDefFoundError onlyIfJUnitIsNotAvailable) {
+ return false;
}
- factory = (theFactory == null) ? new ExceptionFactoryImpl() {
- @Override
- public AssertionError create(String message, String wanted, String actual) {
- return new ArgumentsAreDifferent(message, wanted, actual);
- }
- } : theFactory;
+ return true;
}
/**
- * Returns an AssertionError that describes the fact that the arguments of an invocation are different.
- * If {@link org.opentest4j.AssertionFailedError} is on the class path (used by JUnit 5 and others),
- * it returns a class that extends it. Otherwise, if {@link junit.framework.ComparisonFailure} is on the
- * class path (shipped with JUnit 3 and 4), it will return a class that extends that. This provides
- * better IDE support as the comparison result can be opened in a visual diff. If neither are available,
- * it returns an instance of
- * {@link org.mockito.exceptions.verification.ArgumentsAreDifferent}.
+ * Don't inline this class! It allows create the JUnit-ArgumentsAreDifferent exception without the need to use reflection.
+ * <p>
+ * If JUnit is not available a call to {@link #create(String, String, String)} will throw a {@link NoClassDefFoundError}.
+ * The {@link NoClassDefFoundError} will be thrown by the class loader cause the JUnit class {@link ComparisonFailure}
+ * can't be loaded which is a upper class of ArgumentsAreDifferent.
*/
- public static AssertionError createArgumentsAreDifferentException(String message, String wanted, String actual) {
- return factory.create(message, wanted, actual);
+ private static class JUnitArgsAreDifferent {
+ static AssertionError create(String message, String wanted, String actual) {
+ return new org.mockito.exceptions.verification.junit.ArgumentsAreDifferent(message, wanted, actual);
+ }
}
}
diff --git a/src/main/java/org/mockito/internal/junit/JUnitRule.java b/src/main/java/org/mockito/internal/junit/JUnitRule.java
index 3bd3dac..b825416 100644
--- a/src/main/java/org/mockito/internal/junit/JUnitRule.java
+++ b/src/main/java/org/mockito/internal/junit/JUnitRule.java
@@ -7,10 +7,9 @@ package org.mockito.internal.junit;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.Statement;
import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
import org.mockito.MockitoSession;
import org.mockito.internal.session.MockitoSessionLoggerAdapter;
-import org.mockito.plugins.MockitoLogger;
+import org.mockito.internal.util.MockitoLogger;
import org.mockito.quality.Strictness;
import org.mockito.junit.MockitoRule;
@@ -35,16 +34,12 @@ public class JUnitRule implements MockitoRule {
public Statement apply(final Statement base, final FrameworkMethod method, final Object target) {
return new Statement() {
public void evaluate() throws Throwable {
- if (session == null) {
- session = Mockito.mockitoSession()
- .name(target.getClass().getSimpleName() + "." + method.getName())
- .strictness(strictness)
- .logger(new MockitoSessionLoggerAdapter(logger))
- .initMocks(target)
- .startMocking();
- } else {
- MockitoAnnotations.initMocks(target);
- }
+ session = Mockito.mockitoSession()
+ .name(target.getClass().getSimpleName() + "." + method.getName())
+ .strictness(strictness)
+ .logger(new MockitoSessionLoggerAdapter(logger))
+ .initMocks(target)
+ .startMocking();
Throwable testFailure = evaluateSafely(base);
session.finishMocking(testFailure);
if (testFailure != null) {
diff --git a/src/main/java/org/mockito/internal/junit/MismatchReportingTestListener.java b/src/main/java/org/mockito/internal/junit/MismatchReportingTestListener.java
index d705396..26d4e4e 100644
--- a/src/main/java/org/mockito/internal/junit/MismatchReportingTestListener.java
+++ b/src/main/java/org/mockito/internal/junit/MismatchReportingTestListener.java
@@ -4,7 +4,7 @@
*/
package org.mockito.internal.junit;
-import org.mockito.plugins.MockitoLogger;
+import org.mockito.internal.util.MockitoLogger;
import org.mockito.mock.MockCreationSettings;
import java.util.Collection;
diff --git a/src/main/java/org/mockito/internal/junit/StrictStubsRunnerTestListener.java b/src/main/java/org/mockito/internal/junit/StrictStubsRunnerTestListener.java
index d23431b..9e60c31 100644
--- a/src/main/java/org/mockito/internal/junit/StrictStubsRunnerTestListener.java
+++ b/src/main/java/org/mockito/internal/junit/StrictStubsRunnerTestListener.java
@@ -4,6 +4,7 @@
*/
package org.mockito.internal.junit;
+import org.mockito.internal.creation.settings.CreationSettings;
import org.mockito.mock.MockCreationSettings;
import org.mockito.quality.Strictness;
@@ -21,8 +22,8 @@ public class StrictStubsRunnerTestListener implements MockitoTestListener {
public void onMockCreated(Object mock, MockCreationSettings settings) {
//It is not ideal that we modify the state of MockCreationSettings object
//MockCreationSettings is intended to be an immutable view of the creation settings
- //However, we our previous listeners work this way and it hasn't backfired.
- //Since it is simple and pragmatic, we'll keep it for now.
- settings.getStubbingLookupListeners().add(stubbingLookupListener);
+ //In future, we should start passing MockSettings object to the creation listener
+ //TODO #793 - when completed, we should be able to get rid of the CreationSettings casting below
+ ((CreationSettings) settings).getStubbingLookupListeners().add(stubbingLookupListener);
}
}
diff --git a/src/main/java/org/mockito/internal/junit/StubbingArgMismatches.java b/src/main/java/org/mockito/internal/junit/StubbingArgMismatches.java
index f125f60..3d6342c 100644
--- a/src/main/java/org/mockito/internal/junit/StubbingArgMismatches.java
+++ b/src/main/java/org/mockito/internal/junit/StubbingArgMismatches.java
@@ -4,7 +4,7 @@
*/
package org.mockito.internal.junit;
-import org.mockito.plugins.MockitoLogger;
+import org.mockito.internal.util.MockitoLogger;
import org.mockito.invocation.Invocation;
import java.util.LinkedHashMap;
diff --git a/src/main/java/org/mockito/internal/junit/UniversalTestListener.java b/src/main/java/org/mockito/internal/junit/UniversalTestListener.java
index d681823..66c9dee 100644
--- a/src/main/java/org/mockito/internal/junit/UniversalTestListener.java
+++ b/src/main/java/org/mockito/internal/junit/UniversalTestListener.java
@@ -5,8 +5,7 @@
package org.mockito.internal.junit;
import org.mockito.internal.creation.settings.CreationSettings;
-import org.mockito.internal.listeners.AutoCleanableListener;
-import org.mockito.plugins.MockitoLogger;
+import org.mockito.internal.util.MockitoLogger;
import org.mockito.mock.MockCreationSettings;
import org.mockito.quality.Strictness;
@@ -19,14 +18,13 @@ import java.util.Map;
* Will come handy when we offer tweaking strictness at the method level with annotation.
* Should be relatively easy to improve and offer tweaking strictness per mock.
*/
-public class UniversalTestListener implements MockitoTestListener, AutoCleanableListener {
+public class UniversalTestListener implements MockitoTestListener {
private Strictness currentStrictness;
private final MockitoLogger logger;
private Map<Object, MockCreationSettings> mocks = new IdentityHashMap<Object, MockCreationSettings>();
private DefaultStubbingLookupListener stubbingLookupListener;
- private boolean listenerDirty;
public UniversalTestListener(Strictness initialStrictness, MockitoLogger logger) {
this.currentStrictness = initialStrictness;
@@ -87,19 +85,4 @@ public class UniversalTestListener implements MockitoTestListener, AutoCleanable
this.currentStrictness = strictness;
this.stubbingLookupListener.setCurrentStrictness(strictness);
}
-
- /**
- * See {@link AutoCleanableListener#isListenerDirty()}
- */
- @Override
- public boolean isListenerDirty() {
- return listenerDirty;
- }
-
- /**
- * Marks listener as dirty, scheduled for cleanup when the next session starts
- */
- public void setListenerDirty() {
- this.listenerDirty = true;
- }
}
diff --git a/src/main/java/org/mockito/internal/junit/UnusedStubbings.java b/src/main/java/org/mockito/internal/junit/UnusedStubbings.java
index d45b13d..3505d2c 100644
--- a/src/main/java/org/mockito/internal/junit/UnusedStubbings.java
+++ b/src/main/java/org/mockito/internal/junit/UnusedStubbings.java
@@ -5,7 +5,7 @@
package org.mockito.internal.junit;
import org.mockito.internal.exceptions.Reporter;
-import org.mockito.plugins.MockitoLogger;
+import org.mockito.internal.util.MockitoLogger;
import org.mockito.invocation.Invocation;
import org.mockito.stubbing.Stubbing;
diff --git a/src/main/java/org/mockito/internal/junit/VerificationCollectorImpl.java b/src/main/java/org/mockito/internal/junit/VerificationCollectorImpl.java
index e54d478..7c19d35 100644
--- a/src/main/java/org/mockito/internal/junit/VerificationCollectorImpl.java
+++ b/src/main/java/org/mockito/internal/junit/VerificationCollectorImpl.java
@@ -75,7 +75,7 @@ public class VerificationCollectorImpl implements VerificationCollector {
this.numberOfFailures++;
this.builder.append('\n')
.append(this.numberOfFailures).append(". ")
- .append(message.trim()).append('\n');
+ .append(message.substring(1, message.length()));
}
private class VerificationWrapper implements VerificationMode {
@@ -89,7 +89,7 @@ public class VerificationCollectorImpl implements VerificationCollector {
public void verify(VerificationData data) {
try {
this.delegate.verify(data);
- } catch (AssertionError error) {
+ } catch (MockitoAssertionError error) {
VerificationCollectorImpl.this.append(error.getMessage());
}
}
diff --git a/src/main/java/org/mockito/internal/listeners/AutoCleanableListener.java b/src/main/java/org/mockito/internal/listeners/AutoCleanableListener.java
deleted file mode 100644
index cfd2a53..0000000
--- a/src/main/java/org/mockito/internal/listeners/AutoCleanableListener.java
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2018 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
-package org.mockito.internal.listeners;
-
-/**
- * Listener that is automatically cleaned up (removed from the the global list of subscribers).
- * For now, we don't intend to make this interface public.
- */
-public interface AutoCleanableListener {
-
- /**
- * Indicates that the listener is dirty and should be removed from the subscribers
- */
- boolean isListenerDirty();
-}
diff --git a/src/main/java/org/mockito/internal/listeners/StubbingLookupNotifier.java b/src/main/java/org/mockito/internal/listeners/StubbingLookupNotifier.java
index a0de0c3..3e55001 100644
--- a/src/main/java/org/mockito/internal/listeners/StubbingLookupNotifier.java
+++ b/src/main/java/org/mockito/internal/listeners/StubbingLookupNotifier.java
@@ -6,8 +6,6 @@ package org.mockito.internal.listeners;
import org.mockito.internal.creation.settings.CreationSettings;
import org.mockito.invocation.Invocation;
-import org.mockito.listeners.StubbingLookupEvent;
-import org.mockito.listeners.StubbingLookupListener;
import org.mockito.mock.MockCreationSettings;
import org.mockito.stubbing.Stubbing;
diff --git a/src/main/java/org/mockito/internal/progress/MockingProgressImpl.java b/src/main/java/org/mockito/internal/progress/MockingProgressImpl.java
index 5c4fbbc..2685ddf 100644
--- a/src/main/java/org/mockito/internal/progress/MockingProgressImpl.java
+++ b/src/main/java/org/mockito/internal/progress/MockingProgressImpl.java
@@ -9,7 +9,6 @@ import org.mockito.internal.configuration.GlobalConfiguration;
import org.mockito.internal.debugging.Localized;
import org.mockito.internal.debugging.LocationImpl;
import org.mockito.internal.exceptions.Reporter;
-import org.mockito.internal.listeners.AutoCleanableListener;
import org.mockito.invocation.Location;
import org.mockito.listeners.MockCreationListener;
import org.mockito.listeners.MockitoListener;
@@ -20,8 +19,6 @@ import org.mockito.verification.VerificationMode;
import org.mockito.verification.VerificationStrategy;
import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
import java.util.Set;
import static org.mockito.internal.exceptions.Reporter.unfinishedStubbing;
@@ -157,28 +154,12 @@ public class MockingProgressImpl implements MockingProgress {
}
public void addListener(MockitoListener listener) {
- addListener(listener, listeners);
- }
-
- static void addListener(MockitoListener listener, Set<MockitoListener> listeners) {
- List<MockitoListener> delete = new LinkedList<MockitoListener>();
for (MockitoListener existing : listeners) {
if (existing.getClass().equals(listener.getClass())) {
- if (existing instanceof AutoCleanableListener && ((AutoCleanableListener) existing).isListenerDirty()) {
- //dirty listener means that there was an exception even before the test started
- //if we fail here with redundant mockito listener exception there will be multiple failures causing confusion
- //so we simply remove the existing listener and move on
- delete.add(existing);
- } else {
- Reporter.redundantMockitoListener(listener.getClass().getSimpleName());
- }
+ Reporter.redundantMockitoListener(listener.getClass().getSimpleName());
}
}
- //delete dirty listeners so they don't occupy state/memory and don't receive notifications
- for (MockitoListener toDelete : delete) {
- listeners.remove(toDelete);
- }
- listeners.add(listener);
+ this.listeners.add(listener);
}
public void removeListener(MockitoListener listener) {
diff --git a/src/main/java/org/mockito/internal/reporting/PrintSettings.java b/src/main/java/org/mockito/internal/reporting/PrintSettings.java
index 4fc5992..7986c35 100644
--- a/src/main/java/org/mockito/internal/reporting/PrintSettings.java
+++ b/src/main/java/org/mockito/internal/reporting/PrintSettings.java
@@ -5,6 +5,7 @@
package org.mockito.internal.reporting;
import org.mockito.ArgumentMatcher;
+import org.mockito.internal.invocation.ArgumentsProcessor;
import org.mockito.internal.matchers.text.MatchersPrinter;
import org.mockito.internal.util.MockUtil;
import org.mockito.invocation.Invocation;
@@ -54,7 +55,7 @@ public class PrintSettings {
}
public String print(Invocation invocation) {
- return print(invocation.getArgumentsAsMatchers(), invocation);
+ return print(ArgumentsProcessor.argumentsToMatchers(invocation.getArguments()), invocation);
}
public String print(MatchableInvocation invocation) {
diff --git a/src/main/java/org/mockito/internal/runners/DefaultInternalRunner.java b/src/main/java/org/mockito/internal/runners/DefaultInternalRunner.java
index 93aa32d..2f26ff1 100644
--- a/src/main/java/org/mockito/internal/runners/DefaultInternalRunner.java
+++ b/src/main/java/org/mockito/internal/runners/DefaultInternalRunner.java
@@ -30,29 +30,34 @@ public class DefaultInternalRunner implements InternalRunner {
public Object target;
private MockitoTestListener mockitoTestListener;
- protected Statement withBefores(FrameworkMethod method, final Object target, Statement statement) {
+ protected Statement withBefores(FrameworkMethod method, Object target, Statement statement) {
this.target = target;
- final Statement base = super.withBefores(method, target, statement);
- return new Statement() {
- @Override
- public void evaluate() throws Throwable {
- // get new test listener and add it to the framework
- mockitoTestListener = listenerSupplier.get();
- Mockito.framework().addListener(mockitoTestListener);
- // init annotated mocks before tests
- MockitoAnnotations.initMocks(target);
- base.evaluate();
- }
- };
+ // get new test listener and add it to the framework
+ mockitoTestListener = listenerSupplier.get();
+ Mockito.framework().addListener(mockitoTestListener);
+ // init annotated mocks before tests
+ MockitoAnnotations.initMocks(target);
+ return super.withBefores(method, target, statement);
}
public void run(final RunNotifier notifier) {
RunListener listener = new RunListener() {
+ private boolean started;
Throwable failure;
@Override
+ public void testStarted(Description description) throws Exception {
+ started = true;
+ }
+
+ @Override
public void testFailure(Failure failure) throws Exception {
this.failure = failure.getException();
+ // If the test fails during the setup, `testFinished` is never invoked
+ // Therefore, if we have not started, cleanup the testlistener
+ if (!started && mockitoTestListener != null) {
+ Mockito.framework().removeListener(mockitoTestListener);
+ }
}
@Override
diff --git a/src/main/java/org/mockito/internal/runners/RunnerFactory.java b/src/main/java/org/mockito/internal/runners/RunnerFactory.java
index efdb6b2..61456dc 100644
--- a/src/main/java/org/mockito/internal/runners/RunnerFactory.java
+++ b/src/main/java/org/mockito/internal/runners/RunnerFactory.java
@@ -5,12 +5,12 @@
package org.mockito.internal.runners;
import org.mockito.exceptions.base.MockitoException;
-import org.mockito.internal.configuration.plugins.Plugins;
import org.mockito.internal.junit.MismatchReportingTestListener;
import org.mockito.internal.junit.MockitoTestListener;
import org.mockito.internal.junit.NoOpTestListener;
import org.mockito.internal.junit.StrictStubsRunnerTestListener;
import org.mockito.internal.runners.util.RunnerProvider;
+import org.mockito.internal.util.ConsoleMockitoLogger;
import org.mockito.internal.util.Supplier;
import java.lang.reflect.InvocationTargetException;
@@ -39,7 +39,7 @@ public class RunnerFactory {
public InternalRunner createStrict(Class<?> klass) throws InvocationTargetException {
return create(klass, new Supplier<MockitoTestListener>() {
public MockitoTestListener get() {
- return new MismatchReportingTestListener(Plugins.getMockitoLogger());
+ return new MismatchReportingTestListener(new ConsoleMockitoLogger());
}
});
}
diff --git a/src/main/java/org/mockito/internal/session/DefaultMockitoSessionBuilder.java b/src/main/java/org/mockito/internal/session/DefaultMockitoSessionBuilder.java
index f47ee15..d9b21e5 100644
--- a/src/main/java/org/mockito/internal/session/DefaultMockitoSessionBuilder.java
+++ b/src/main/java/org/mockito/internal/session/DefaultMockitoSessionBuilder.java
@@ -5,9 +5,9 @@
package org.mockito.internal.session;
import org.mockito.MockitoSession;
-import org.mockito.internal.configuration.plugins.Plugins;
import org.mockito.internal.framework.DefaultMockitoSession;
-import org.mockito.plugins.MockitoLogger;
+import org.mockito.internal.util.ConsoleMockitoLogger;
+import org.mockito.internal.util.MockitoLogger;
import org.mockito.quality.Strictness;
import org.mockito.session.MockitoSessionBuilder;
import org.mockito.session.MockitoSessionLogger;
@@ -74,7 +74,7 @@ public class DefaultMockitoSessionBuilder implements MockitoSessionBuilder {
effectiveName = this.name == null ? lastTestClassInstance.getClass().getName() : this.name;
}
Strictness effectiveStrictness = this.strictness == null ? Strictness.STRICT_STUBS : this.strictness;
- MockitoLogger logger = this.logger == null ? Plugins.getMockitoLogger() : new MockitoLoggerAdapter(this.logger);
+ MockitoLogger logger = this.logger == null ? new ConsoleMockitoLogger() : new MockitoLoggerAdapter(this.logger);
return new DefaultMockitoSession(effectiveTestClassInstances, effectiveName, effectiveStrictness, logger);
}
}
diff --git a/src/main/java/org/mockito/internal/session/MockitoLoggerAdapter.java b/src/main/java/org/mockito/internal/session/MockitoLoggerAdapter.java
index 2197317..b7329e7 100644
--- a/src/main/java/org/mockito/internal/session/MockitoLoggerAdapter.java
+++ b/src/main/java/org/mockito/internal/session/MockitoLoggerAdapter.java
@@ -4,7 +4,7 @@
*/
package org.mockito.internal.session;
-import org.mockito.plugins.MockitoLogger;
+import org.mockito.internal.util.MockitoLogger;
import org.mockito.session.MockitoSessionLogger;
class MockitoLoggerAdapter implements MockitoLogger {
diff --git a/src/main/java/org/mockito/internal/session/MockitoSessionLoggerAdapter.java b/src/main/java/org/mockito/internal/session/MockitoSessionLoggerAdapter.java
index f4770c5..2e8634b 100644
--- a/src/main/java/org/mockito/internal/session/MockitoSessionLoggerAdapter.java
+++ b/src/main/java/org/mockito/internal/session/MockitoSessionLoggerAdapter.java
@@ -4,7 +4,7 @@
*/
package org.mockito.internal.session;
-import org.mockito.plugins.MockitoLogger;
+import org.mockito.internal.util.MockitoLogger;
import org.mockito.session.MockitoSessionLogger;
public class MockitoSessionLoggerAdapter implements MockitoSessionLogger {
diff --git a/src/main/java/org/mockito/internal/stubbing/BaseStubbing.java b/src/main/java/org/mockito/internal/stubbing/BaseStubbing.java
index 4c86cbd..6dd99cd 100644
--- a/src/main/java/org/mockito/internal/stubbing/BaseStubbing.java
+++ b/src/main/java/org/mockito/internal/stubbing/BaseStubbing.java
@@ -4,31 +4,17 @@
*/
package org.mockito.internal.stubbing;
+import static org.mockito.internal.exceptions.Reporter.notAnException;
+import static org.mockito.internal.progress.ThreadSafeMockingProgress.mockingProgress;
+import static org.objenesis.ObjenesisHelper.newInstance;
+
import org.mockito.internal.stubbing.answers.CallsRealMethods;
import org.mockito.internal.stubbing.answers.Returns;
import org.mockito.internal.stubbing.answers.ThrowsException;
-import org.mockito.stubbing.Answer;
import org.mockito.stubbing.OngoingStubbing;
-import static org.mockito.internal.exceptions.Reporter.notAnException;
-import static org.mockito.internal.progress.ThreadSafeMockingProgress.mockingProgress;
-import static org.objenesis.ObjenesisHelper.newInstance;
-
public abstract class BaseStubbing<T> implements OngoingStubbing<T> {
-
- // Keep strong ref to mock preventing premature garbage collection when using 'One-liner stubs'. See #1541.
- private final Object strongMockRef;
-
- BaseStubbing(Object mock) {
- this.strongMockRef = mock;
- }
-
- @Override
- public OngoingStubbing<T> then(Answer<?> answer) {
- return thenAnswer(answer);
- }
-
@Override
public OngoingStubbing<T> thenReturn(T value) {
return thenAnswer(new Returns(value));
@@ -93,12 +79,6 @@ public abstract class BaseStubbing<T> implements OngoingStubbing<T> {
public OngoingStubbing<T> thenCallRealMethod() {
return thenAnswer(new CallsRealMethods());
}
-
- @Override
- @SuppressWarnings("unchecked")
- public <M> M getMock() {
- return (M) this.strongMockRef;
- }
}
diff --git a/src/main/java/org/mockito/internal/stubbing/ConsecutiveStubbing.java b/src/main/java/org/mockito/internal/stubbing/ConsecutiveStubbing.java
index 32ef8ee..a5cdc04 100644
--- a/src/main/java/org/mockito/internal/stubbing/ConsecutiveStubbing.java
+++ b/src/main/java/org/mockito/internal/stubbing/ConsecutiveStubbing.java
@@ -8,17 +8,23 @@ import org.mockito.stubbing.Answer;
import org.mockito.stubbing.OngoingStubbing;
public class ConsecutiveStubbing<T> extends BaseStubbing<T> {
+ private final InvocationContainerImpl invocationContainerImpl;
- private final InvocationContainerImpl invocationContainer;
-
- ConsecutiveStubbing(InvocationContainerImpl invocationContainer) {
- super(invocationContainer.invokedMock());
- this.invocationContainer = invocationContainer;
+ public ConsecutiveStubbing(InvocationContainerImpl invocationContainerImpl) {
+ this.invocationContainerImpl = invocationContainerImpl;
}
public OngoingStubbing<T> thenAnswer(Answer<?> answer) {
- invocationContainer.addConsecutiveAnswer(answer);
+ invocationContainerImpl.addConsecutiveAnswer(answer);
return this;
}
+ public OngoingStubbing<T> then(Answer<?> answer) {
+ return thenAnswer(answer);
+ }
+
+ @SuppressWarnings("unchecked")
+ public <M> M getMock() {
+ return (M) invocationContainerImpl.invokedMock();
+ }
}
diff --git a/src/main/java/org/mockito/internal/stubbing/OngoingStubbingImpl.java b/src/main/java/org/mockito/internal/stubbing/OngoingStubbingImpl.java
index 4191604..cd27c39 100644
--- a/src/main/java/org/mockito/internal/stubbing/OngoingStubbingImpl.java
+++ b/src/main/java/org/mockito/internal/stubbing/OngoingStubbingImpl.java
@@ -19,7 +19,6 @@ public class OngoingStubbingImpl<T> extends BaseStubbing<T> {
private Strictness strictness;
public OngoingStubbingImpl(InvocationContainerImpl invocationContainer) {
- super(invocationContainer.invokedMock());
this.invocationContainer = invocationContainer;
}
@@ -33,11 +32,22 @@ public class OngoingStubbingImpl<T> extends BaseStubbing<T> {
return new ConsecutiveStubbing<T>(invocationContainer);
}
+ @Override
+ public OngoingStubbing<T> then(Answer<?> answer) {
+ return thenAnswer(answer);
+ }
+
public List<Invocation> getRegisteredInvocations() {
//TODO interface for tests
return invocationContainer.getInvocations();
}
+ @Override
+ @SuppressWarnings("unchecked")
+ public <M> M getMock() {
+ return (M) invocationContainer.invokedMock();
+ }
+
public void setStrictness(Strictness strictness) {
this.strictness = strictness;
}
diff --git a/src/main/java/org/mockito/internal/stubbing/StubberImpl.java b/src/main/java/org/mockito/internal/stubbing/StubberImpl.java
index 42795a7..2172809 100644
--- a/src/main/java/org/mockito/internal/stubbing/StubberImpl.java
+++ b/src/main/java/org/mockito/internal/stubbing/StubberImpl.java
@@ -87,16 +87,12 @@ public class StubberImpl implements Stubber {
mockingProgress().reset();
throw notAnException();
}
- Throwable e = null;
+ Throwable e;
try {
e = newInstance(toBeThrown);
- } finally {
- if (e == null) {
- //this means that an exception or error was thrown when trying to create new instance
- //we don't want 'catch' statement here because we want the exception to be thrown to the user
- //however, we do want to clean up state (e.g. "stubbing started").
- mockingProgress().reset();
- }
+ } catch (RuntimeException instantiationError) {
+ mockingProgress().reset();
+ throw instantiationError;
}
return doThrow(e);
}
diff --git a/src/main/java/org/mockito/internal/stubbing/answers/AnswerFunctionalInterfaces.java b/src/main/java/org/mockito/internal/stubbing/answers/AnswerFunctionalInterfaces.java
index eaa6493..e1a92a4 100644
--- a/src/main/java/org/mockito/internal/stubbing/answers/AnswerFunctionalInterfaces.java
+++ b/src/main/java/org/mockito/internal/stubbing/answers/AnswerFunctionalInterfaces.java
@@ -11,13 +11,11 @@ import org.mockito.stubbing.Answer2;
import org.mockito.stubbing.Answer3;
import org.mockito.stubbing.Answer4;
import org.mockito.stubbing.Answer5;
-import org.mockito.stubbing.Answer6;
import org.mockito.stubbing.VoidAnswer1;
import org.mockito.stubbing.VoidAnswer2;
import org.mockito.stubbing.VoidAnswer3;
import org.mockito.stubbing.VoidAnswer4;
import org.mockito.stubbing.VoidAnswer5;
-import org.mockito.stubbing.VoidAnswer6;
/**
* Functional interfaces to make it easy to implement answers in Java 8
@@ -238,60 +236,4 @@ public class AnswerFunctionalInterfaces {
}
};
}
-
- /**
- * Construct an answer from a six parameter answer interface
- *
- * @param answer answer interface
- * @param <T> return type
- * @param <A> input parameter 1 type
- * @param <B> input parameter 2 type
- * @param <C> input parameter 3 type
- * @param <D> input parameter 4 type
- * @param <E> input parameter 5 type
- * @param <F> input parameter 6 type
- * @return a new answer object
- */
- public static <T, A, B, C, D, E, F> Answer<T> toAnswer(final Answer6<T, A, B, C, D, E, F> answer) {
- return new Answer<T>() {
- @SuppressWarnings("unchecked")
- public T answer(InvocationOnMock invocation) throws Throwable {
- return answer.answer(
- (A)invocation.getArgument(0),
- (B)invocation.getArgument(1),
- (C)invocation.getArgument(2),
- (D)invocation.getArgument(3),
- (E)invocation.getArgument(4),
- (F)invocation.getArgument(5));
- }
- };
- }
-
- /**
- * Construct an answer from a five parameter answer interface
-
- * @param answer answer interface
- * @param <A> input parameter 1 type
- * @param <B> input parameter 2 type
- * @param <C> input parameter 3 type
- * @param <D> input parameter 4 type
- * @param <E> input parameter 5 type
- * @param <F> input parameter 6 type
- * @return a new answer object
- */
- public static <A, B, C, D, E, F> Answer<Void> toAnswer(final VoidAnswer6<A, B, C, D, E, F> answer) {
- return new Answer<Void>() {
- @SuppressWarnings("unchecked")
- public Void answer(InvocationOnMock invocation) throws Throwable {
- answer.answer(
- (A)invocation.getArgument(0),
- (B)invocation.getArgument(1),
- (C)invocation.getArgument(2),
- (D)invocation.getArgument(3),
- (E)invocation.getArgument(4),
- (F)invocation.getArgument(5));
- return null;
- }
- };
- }
}
diff --git a/src/main/java/org/mockito/internal/stubbing/defaultanswers/ForwardsInvocations.java b/src/main/java/org/mockito/internal/stubbing/defaultanswers/ForwardsInvocations.java
index 7ef283c..9165142 100644
--- a/src/main/java/org/mockito/internal/stubbing/defaultanswers/ForwardsInvocations.java
+++ b/src/main/java/org/mockito/internal/stubbing/defaultanswers/ForwardsInvocations.java
@@ -40,11 +40,6 @@ public class ForwardsInvocations implements Answer<Object>, Serializable {
}
Object[] rawArguments = ((Invocation) invocation).getRawArguments();
- try {
- delegateMethod.setAccessible(true);
- } catch (SecurityException ignore) {
- // try to invoke anyway
- }
return delegateMethod.invoke(delegatedObject, rawArguments);
} catch (NoSuchMethodException e) {
throw delegatedMethodDoesNotExistOnDelegate(mockMethod, invocation.getMock(), delegatedObject);
diff --git a/src/main/java/org/mockito/internal/stubbing/defaultanswers/RetrieveGenericsForDefaultAnswers.java b/src/main/java/org/mockito/internal/stubbing/defaultanswers/RetrieveGenericsForDefaultAnswers.java
deleted file mode 100644
index 979c8f7..0000000
--- a/src/main/java/org/mockito/internal/stubbing/defaultanswers/RetrieveGenericsForDefaultAnswers.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
-package org.mockito.internal.stubbing.defaultanswers;
-
-import java.lang.reflect.GenericArrayType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import org.mockito.internal.MockitoCore;
-import org.mockito.internal.util.MockUtil;
-import org.mockito.internal.util.reflection.GenericMetadataSupport;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.mock.MockCreationSettings;
-
-class RetrieveGenericsForDefaultAnswers {
-
- private static final MockitoCore MOCKITO_CORE = new MockitoCore();
-
- static Object returnTypeForMockWithCorrectGenerics(
- InvocationOnMock invocation, AnswerCallback answerCallback) {
- Class<?> type = invocation.getMethod().getReturnType();
-
- final Type returnType = invocation.getMethod().getGenericReturnType();
-
- Object defaultReturnValue = null;
-
- if (returnType instanceof TypeVariable) {
- type = findTypeFromGeneric(invocation, (TypeVariable) returnType);
- if (type != null) {
- defaultReturnValue = delegateChains(type);
- }
- }
-
- if (defaultReturnValue != null) {
- return defaultReturnValue;
- }
-
- if (type != null) {
- if (!MOCKITO_CORE.isTypeMockable(type)) {
- return null;
- }
-
- return answerCallback.apply(type);
- }
-
- return answerCallback.apply(null);
- }
-
- /**
- * Try to resolve the result value using {@link ReturnsEmptyValues} and {@link ReturnsMoreEmptyValues}.
- *
- * This will try to use all parent class (superclass & interfaces) to retrieve the value..
- *
- * @param type the return type of the method
- * @return a non-null instance if the type has been resolve. Null otherwise.
- */
- private static Object delegateChains(final Class<?> type) {
- final ReturnsEmptyValues returnsEmptyValues = new ReturnsEmptyValues();
- Object result = returnsEmptyValues.returnValueFor(type);
-
- if (result == null) {
- Class<?> emptyValueForClass = type;
- while (emptyValueForClass != null && result == null) {
- final Class<?>[] classes = emptyValueForClass.getInterfaces();
- for (Class<?> clazz : classes) {
- result = returnsEmptyValues.returnValueFor(clazz);
- if (result != null) {
- break;
- }
- }
- emptyValueForClass = emptyValueForClass.getSuperclass();
- }
- }
-
- if (result == null) {
- result = new ReturnsMoreEmptyValues().returnValueFor(type);
- }
-
- return result;
- }
-
- /**
- * Retrieve the expected type when it came from a primitive. If the type cannot be retrieve, return null.
- *
- * @param invocation the current invocation
- * @param returnType the expected return type
- * @return the type or null if not found
- */
- private static Class<?> findTypeFromGeneric(final InvocationOnMock invocation, final TypeVariable returnType) {
- // Class level
- final MockCreationSettings mockSettings = MockUtil.getMockHandler(invocation.getMock()).getMockSettings();
- final GenericMetadataSupport returnTypeSupport = GenericMetadataSupport
- .inferFrom(mockSettings.getTypeToMock())
- .resolveGenericReturnType(invocation.getMethod());
- final Class<?> rawType = returnTypeSupport.rawType();
-
- // Method level
- if (rawType == Object.class) {
- return findTypeFromGenericInArguments(invocation, returnType);
- }
- return rawType;
- }
-
- /**
- * Find a return type using generic arguments provided by the calling method.
- *
- * @param invocation the current invocation
- * @param returnType the expected return type
- * @return the return type or null if the return type cannot be found
- */
- private static Class<?> findTypeFromGenericInArguments(final InvocationOnMock invocation, final TypeVariable returnType) {
- final Type[] parameterTypes = invocation.getMethod().getGenericParameterTypes();
- for (int i = 0; i < parameterTypes.length; i++) {
- Type argType = parameterTypes[i];
- if (returnType.equals(argType)) {
- Object argument = invocation.getArgument(i);
-
- if (argument == null) {
- return null;
- }
-
- return argument.getClass();
- }
- if (argType instanceof GenericArrayType) {
- argType = ((GenericArrayType) argType).getGenericComponentType();
- if (returnType.equals(argType)) {
- return invocation.getArgument(i).getClass();
- }
- }
- }
- return null;
- }
-
- interface AnswerCallback {
- Object apply(Class<?> type);
- }
-}
diff --git a/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsDeepStubs.java b/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsDeepStubs.java
index 356b2e6..3909ff0 100644
--- a/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsDeepStubs.java
+++ b/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsDeepStubs.java
@@ -25,7 +25,7 @@ import static org.mockito.Mockito.withSettings;
/**
* Returning deep stub implementation.
*
- * <p>Will return previously created mock if the invocation matches.
+ * Will return previously created mock if the invocation matches.
*
* <p>Supports nested generic information, with this answer you can write code like this :
*
@@ -37,8 +37,6 @@ import static org.mockito.Mockito.withSettings;
* </code></pre>
* </p>
*
- * <p>However this answer does not support generics information when the mock has been deserialized.
- *
* @see org.mockito.Mockito#RETURNS_DEEP_STUBS
* @see org.mockito.Answers#RETURNS_DEEP_STUBS
*/
@@ -48,22 +46,13 @@ public class ReturnsDeepStubs implements Answer<Object>, Serializable {
public Object answer(InvocationOnMock invocation) throws Throwable {
GenericMetadataSupport returnTypeGenericMetadata =
- actualParameterizedType(invocation.getMock()).resolveGenericReturnType(invocation.getMethod());
+ actualParameterizedType(invocation.getMock()).resolveGenericReturnType(invocation.getMethod());
Class<?> rawType = returnTypeGenericMetadata.rawType();
if (!mockitoCore().isTypeMockable(rawType)) {
return delegate().returnValueFor(rawType);
}
- // When dealing with erased generics, we only receive the Object type as rawType. At this
- // point, there is nothing to salvage for Mockito. Instead of trying to be smart and generate
- // a mock that would potentially match the return signature, instead return `null`. This
- // is valid per the CheckCast JVM instruction and is better than causing a ClassCastException
- // on runtime.
- if (rawType.equals(Object.class) && !returnTypeGenericMetadata.hasRawExtraInterfaces()) {
- return null;
- }
-
return deepStub(invocation, returnTypeGenericMetadata);
}
@@ -80,9 +69,9 @@ public class ReturnsDeepStubs implements Answer<Object>, Serializable {
// record deep stub answer
StubbedInvocationMatcher stubbing = recordDeepStubAnswer(
- newDeepStubMock(returnTypeGenericMetadata, invocation.getMock()),
- container
- );
+ newDeepStubMock(returnTypeGenericMetadata, invocation.getMock()),
+ container
+ );
// deep stubbing creates a stubbing and immediately uses it
// so the stubbing is actually used by the same invocation
@@ -99,24 +88,24 @@ public class ReturnsDeepStubs implements Answer<Object>, Serializable {
* {@link ReturnsDeepStubs} answer in which we will store the returned type generic metadata.
*
* @param returnTypeGenericMetadata The metadata to use to create the new mock.
- * @param parentMock The parent of the current deep stub mock.
+ * @param parentMock The parent of the current deep stub mock.
* @return The mock
*/
private Object newDeepStubMock(GenericMetadataSupport returnTypeGenericMetadata, Object parentMock) {
MockCreationSettings parentMockSettings = MockUtil.getMockSettings(parentMock);
return mockitoCore().mock(
- returnTypeGenericMetadata.rawType(),
- withSettingsUsing(returnTypeGenericMetadata, parentMockSettings)
- );
+ returnTypeGenericMetadata.rawType(),
+ withSettingsUsing(returnTypeGenericMetadata, parentMockSettings)
+ );
}
private MockSettings withSettingsUsing(GenericMetadataSupport returnTypeGenericMetadata, MockCreationSettings parentMockSettings) {
MockSettings mockSettings = returnTypeGenericMetadata.hasRawExtraInterfaces() ?
- withSettings().extraInterfaces(returnTypeGenericMetadata.rawExtraInterfaces())
- : withSettings();
+ withSettings().extraInterfaces(returnTypeGenericMetadata.rawExtraInterfaces())
+ : withSettings();
return propagateSerializationSettings(mockSettings, parentMockSettings)
- .defaultAnswer(returnsDeepStubsAnswerUsing(returnTypeGenericMetadata));
+ .defaultAnswer(returnsDeepStubsAnswerUsing(returnTypeGenericMetadata));
}
private MockSettings propagateSerializationSettings(MockSettings mockSettings, MockCreationSettings parentMockSettings) {
@@ -150,15 +139,6 @@ public class ReturnsDeepStubs implements Answer<Object>, Serializable {
protected GenericMetadataSupport actualParameterizedType(Object mock) {
return returnTypeGenericMetadata;
}
-
- /**
- * Generics support and serialization with deep stubs don't work together.
- * <p>
- * The issue is that GenericMetadataSupport is not serializable because
- * the type elements inferred via reflection are not serializable. Supporting
- * serialization would require to replace all types coming from the Java reflection
- * with our own and still managing type equality with the JDK ones.
- */
private Object writeReplace() throws IOException {
return Mockito.RETURNS_DEEP_STUBS;
}
@@ -172,7 +152,6 @@ public class ReturnsDeepStubs implements Answer<Object>, Serializable {
DeeplyStubbedAnswer(Object mock) {
this.mock = mock;
}
-
public Object answer(InvocationOnMock invocation) throws Throwable {
return mock;
}
diff --git a/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsMocks.java b/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsMocks.java
index 5d4befe..302e4df 100755
--- a/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsMocks.java
+++ b/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsMocks.java
@@ -4,36 +4,33 @@
*/
package org.mockito.internal.stubbing.defaultanswers;
-import java.io.Serializable;
-import org.mockito.Mockito;
+import org.mockito.internal.MockitoCore;
import org.mockito.internal.creation.MockSettingsImpl;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
+import java.io.Serializable;
+
public class ReturnsMocks implements Answer<Object>, Serializable {
private static final long serialVersionUID = -6755257986994634579L;
+ private final MockitoCore mockitoCore = new MockitoCore();
private final Answer<Object> delegate = new ReturnsMoreEmptyValues();
- @Override
- public Object answer(final InvocationOnMock invocation) throws Throwable {
- Object defaultReturnValue = delegate.answer(invocation);
+ public Object answer(InvocationOnMock invocation) throws Throwable {
+ Object ret = delegate.answer(invocation);
+ if (ret != null) {
+ return ret;
+ }
+
+ return returnValueFor(invocation.getMethod().getReturnType());
+ }
- if (defaultReturnValue != null) {
- return defaultReturnValue;
+ Object returnValueFor(Class<?> clazz) {
+ if (!mockitoCore.isTypeMockable(clazz)) {
+ return null;
}
- return RetrieveGenericsForDefaultAnswers.returnTypeForMockWithCorrectGenerics(invocation,
- new RetrieveGenericsForDefaultAnswers.AnswerCallback() {
- @Override
- public Object apply(Class<?> type) {
- if (type == null) {
- type = invocation.getMethod().getReturnType();
- }
-
- return Mockito
- .mock(type, new MockSettingsImpl<Object>().defaultAnswer(ReturnsMocks.this));
- }
- });
+ return mockitoCore.mock(clazz, new MockSettingsImpl().defaultAnswer(this));
}
}
diff --git a/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsSmartNulls.java b/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsSmartNulls.java
index 6cf50c7..7487e89 100644
--- a/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsSmartNulls.java
+++ b/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsSmartNulls.java
@@ -8,6 +8,8 @@ import static org.mockito.internal.exceptions.Reporter.smartNullPointerException
import static org.mockito.internal.util.ObjectMethodsGuru.isToStringMethod;
import java.io.Serializable;
+import java.lang.reflect.Modifier;
+
import org.mockito.Mockito;
import org.mockito.internal.debugging.LocationImpl;
import org.mockito.invocation.InvocationOnMock;
@@ -38,34 +40,24 @@ public class ReturnsSmartNulls implements Answer<Object>, Serializable {
private final Answer<Object> delegate = new ReturnsMoreEmptyValues();
- @Override
public Object answer(final InvocationOnMock invocation) throws Throwable {
Object defaultReturnValue = delegate.answer(invocation);
-
if (defaultReturnValue != null) {
return defaultReturnValue;
}
-
- return RetrieveGenericsForDefaultAnswers.returnTypeForMockWithCorrectGenerics(invocation,
- new RetrieveGenericsForDefaultAnswers.AnswerCallback() {
- @Override
- public Object apply(Class<?> type) {
- if (type == null) {
- return null;
- }
-
- return Mockito.mock(type, new ThrowsSmartNullPointer(invocation, new LocationImpl()));
- }
- });
+ Class<?> type = invocation.getMethod().getReturnType();
+ if (!type.isPrimitive() && !Modifier.isFinal(type.getModifiers())) {
+ final Location location = new LocationImpl();
+ return Mockito.mock(type, new ThrowsSmartNullPointer(invocation, location));
+ }
+ return null;
}
private static class ThrowsSmartNullPointer implements Answer {
-
private final InvocationOnMock unstubbedInvocation;
-
private final Location location;
- ThrowsSmartNullPointer(InvocationOnMock unstubbedInvocation, Location location) {
+ public ThrowsSmartNullPointer(InvocationOnMock unstubbedInvocation, Location location) {
this.unstubbedInvocation = unstubbedInvocation;
this.location = location;
}
@@ -73,7 +65,7 @@ public class ReturnsSmartNulls implements Answer<Object>, Serializable {
public Object answer(InvocationOnMock currentInvocation) throws Throwable {
if (isToStringMethod(currentInvocation.getMethod())) {
return "SmartNull returned by this unstubbed method call on a mock:\n" +
- unstubbedInvocation.toString();
+ unstubbedInvocation.toString();
}
throw smartNullPointerException(unstubbedInvocation.toString(), location);
diff --git a/src/main/java/org/mockito/internal/util/ConsoleMockitoLogger.java b/src/main/java/org/mockito/internal/util/ConsoleMockitoLogger.java
index 3eb8939..d8df8eb 100644
--- a/src/main/java/org/mockito/internal/util/ConsoleMockitoLogger.java
+++ b/src/main/java/org/mockito/internal/util/ConsoleMockitoLogger.java
@@ -4,8 +4,6 @@
*/
package org.mockito.internal.util;
-import org.mockito.plugins.MockitoLogger;
-
public class ConsoleMockitoLogger implements MockitoLogger {
/* (non-Javadoc)
diff --git a/src/main/java/org/mockito/internal/util/reflection/GenericMetadataSupport.java b/src/main/java/org/mockito/internal/util/reflection/GenericMetadataSupport.java
index 80cbf65..8efd384 100644
--- a/src/main/java/org/mockito/internal/util/reflection/GenericMetadataSupport.java
+++ b/src/main/java/org/mockito/internal/util/reflection/GenericMetadataSupport.java
@@ -8,23 +8,8 @@ package org.mockito.internal.util.reflection;
import org.mockito.exceptions.base.MockitoException;
import org.mockito.internal.util.Checks;
-import java.lang.reflect.GenericArrayType;
-import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.lang.reflect.WildcardType;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Queue;
-import java.util.Set;
+import java.lang.reflect.*;
+import java.util.*;
/**
@@ -32,20 +17,20 @@ import java.util.Set;
* and accessible members.
*
* <p>
- * The main idea of this code is to create a Map that will help to resolve return types.
- * In order to actually work with nested generics, this map will have to be passed along new instances
- * as a type context.
+ * The main idea of this code is to create a Map that will help to resolve return types.
+ * In order to actually work with nested generics, this map will have to be passed along new instances
+ * as a type context.
* </p>
*
* <p>
- * Hence :
- * <ul>
- * <li>A new instance representing the metadata is created using the {@link #inferFrom(Type)} method from a real
- * <code>Class</code> or from a <code>ParameterizedType</code>, other types are not yet supported.</li>
+ * Hence :
+ * <ul>
+ * <li>A new instance representing the metadata is created using the {@link #inferFrom(Type)} method from a real
+ * <code>Class</code> or from a <code>ParameterizedType</code>, other types are not yet supported.</li>
*
- * <li>Then from this metadata, we can extract meta-data for a generic return type of a method, using
- * {@link #resolveGenericReturnType(Method)}.</li>
- * </ul>
+ * <li>Then from this metadata, we can extract meta-data for a generic return type of a method, using
+ * {@link #resolveGenericReturnType(Method)}.</li>
+ * </ul>
* </p>
*
* <p>
@@ -112,9 +97,8 @@ public abstract class GenericMetadataSupport {
}
if (type instanceof TypeVariable) {
/*
- * If type is a TypeVariable, then it is needed to gather data elsewhere.
- * Usually TypeVariables are declared on the class definition, such as such
- * as List<E>.
+ * If type is a TypeVariable, then it is needed to gather data elsewhere. Usually TypeVariables are declared
+ * on the class definition, such as such as List<E>.
*/
return extractRawTypeOf(contextualActualTypeParameters.get(type));
}
@@ -132,23 +116,6 @@ public abstract class GenericMetadataSupport {
TypeVariable<?> typeParameter = typeParameters[i];
Type actualTypeArgument = actualTypeArguments[i];
- if (actualTypeArgument instanceof TypeVariable) {
- /*
- * If actualTypeArgument is a TypeVariable, and it is not present in
- * the context map then it is needed to try harder to gather more data
- * from the type argument itself. In some case the type argument do
- * define upper bounds, this allow to look for them if not in the
- * context map.
- */
- registerTypeVariableIfNotPresent((TypeVariable<?>) actualTypeArgument);
-
- // Prevent registration of a cycle of TypeVariables. This can happen when we are processing
- // type parameters in a Method, while we already processed the type parameters of a class.
- if (contextualActualTypeParameters.containsKey(typeParameter)) {
- continue;
- }
- }
-
if (actualTypeArgument instanceof WildcardType) {
contextualActualTypeParameters.put(typeParameter, boundsOf((WildcardType) actualTypeArgument));
} else if (typeParameter != actualTypeArgument) {
@@ -174,7 +141,7 @@ public abstract class GenericMetadataSupport {
/**
* @param typeParameter The TypeVariable parameter
* @return A {@link BoundedType} for easy bound information, if first bound is a TypeVariable
- * then retrieve BoundedType of this TypeVariable
+ * then retrieve BoundedType of this TypeVariable
*/
private BoundedType boundsOf(TypeVariable<?> typeParameter) {
if (typeParameter.getBounds()[0] instanceof TypeVariable) {
@@ -186,17 +153,13 @@ public abstract class GenericMetadataSupport {
/**
* @param wildCard The WildCard type
* @return A {@link BoundedType} for easy bound information, if first bound is a TypeVariable
- * then retrieve BoundedType of this TypeVariable
+ * then retrieve BoundedType of this TypeVariable
*/
private BoundedType boundsOf(WildcardType wildCard) {
/*
* According to JLS(http://docs.oracle.com/javase/specs/jls/se5.0/html/typesValues.html#4.5.1):
- * - Lower and upper can't coexist: (for instance, this is not allowed:
- * <? extends List<String> & super MyInterface>)
- * - Multiple concrete type bounds are not supported (for instance, this is not allowed:
- * <? extends ArrayList<String> & MyInterface>)
- * But the following form is possible where there is a single concrete tyep bound followed by interface type bounds
- * <T extends List<String> & Comparable>
+ * - Lower and upper can't coexist: (for instance, this is not allowed: <? extends List<String> & super MyInterface>)
+ * - Multiple bounds are not supported (for instance, this is not allowed: <? extends List<String> & MyInterface>)
*/
WildCardBoundedType wildCardBoundedType = new WildCardBoundedType(wildCard);
@@ -272,7 +235,7 @@ public abstract class GenericMetadataSupport {
// logger.log("Method '" + method.toGenericString() + "' has return type : " + genericReturnType.getClass().getInterfaces()[0].getSimpleName() + " : " + genericReturnType);
int arity = 0;
- while (genericReturnType instanceof GenericArrayType) {
+ while(genericReturnType instanceof GenericArrayType) {
arity++;
genericReturnType = ((GenericArrayType) genericReturnType).getGenericComponentType();
}
@@ -304,8 +267,8 @@ public abstract class GenericMetadataSupport {
* Create an new instance of {@link GenericMetadataSupport} inferred from a {@link Type}.
*
* <p>
- * At the moment <code>type</code> can only be a {@link Class} or a {@link ParameterizedType}, otherwise
- * it'll throw a {@link MockitoException}.
+ * At the moment <code>type</code> can only be a {@link Class} or a {@link ParameterizedType}, otherwise
+ * it'll throw a {@link MockitoException}.
* </p>
*
* @param type The class from which the {@link GenericMetadataSupport} should be built.
@@ -331,7 +294,7 @@ public abstract class GenericMetadataSupport {
/**
* Generic metadata implementation for {@link Class}.
- * <p>
+ *
* Offer support to retrieve generic metadata on a {@link Class} by reading type parameters and type variables on
* the class and its ancestors and interfaces.
*/
@@ -353,10 +316,10 @@ public abstract class GenericMetadataSupport {
/**
* Generic metadata implementation for "standalone" {@link ParameterizedType}.
- * <p>
+ *
* Offer support to retrieve generic metadata on a {@link ParameterizedType} by reading type variables of
* the related raw type and declared type variable of this parameterized type.
- * <p>
+ *
* This class is not designed to work on ParameterizedType returned by {@link Method#getGenericReturnType()}, as
* the ParameterizedType instance return in these cases could have Type Variables that refer to type declaration(s).
* That's what meant the "standalone" word at the beginning of the Javadoc.
@@ -418,7 +381,6 @@ public abstract class GenericMetadataSupport {
private final TypeVariable<?> typeVariable;
private final TypeVariable<?>[] typeParameters;
private Class<?> rawType;
- private List<Type> extraInterfaces;
public TypeVariableReturnType(GenericMetadataSupport source, TypeVariable<?>[] typeParameters, TypeVariable<?> typeVariable) {
this.typeParameters = typeParameters;
@@ -437,7 +399,7 @@ public abstract class GenericMetadataSupport {
for (Type type : typeVariable.getBounds()) {
registerTypeVariablesOn(type);
}
- registerTypeParametersOn(new TypeVariable[]{typeVariable});
+ registerTypeParametersOn(new TypeVariable[] { typeVariable });
registerTypeVariablesOn(getActualTypeArgumentFor(typeVariable));
}
@@ -451,18 +413,15 @@ public abstract class GenericMetadataSupport {
@Override
public List<Type> extraInterfaces() {
- if (extraInterfaces != null) {
- return extraInterfaces;
- }
Type type = extractActualBoundedTypeOf(typeVariable);
if (type instanceof BoundedType) {
- return extraInterfaces = Arrays.asList(((BoundedType) type).interfaceBounds());
+ return Arrays.asList(((BoundedType) type).interfaceBounds());
}
if (type instanceof ParameterizedType) {
- return extraInterfaces = Collections.singletonList(type);
+ return Collections.singletonList(type);
}
if (type instanceof Class) {
- return extraInterfaces = Collections.emptyList();
+ return Collections.emptyList();
}
throw new MockitoException("Cannot extract extra-interfaces from '" + typeVariable + "' : '" + type + "'");
}
@@ -477,7 +436,7 @@ public abstract class GenericMetadataSupport {
for (Type extraInterface : extraInterfaces) {
Class<?> rawInterface = extractRawTypeOf(extraInterface);
// avoid interface collision with actual raw type (with typevariables, resolution ca be quite aggressive)
- if (!rawType().equals(rawInterface)) {
+ if(!rawType().equals(rawInterface)) {
rawExtraInterfaces.add(rawInterface);
}
}
@@ -549,6 +508,7 @@ public abstract class GenericMetadataSupport {
}
+
/**
* Type representing bounds of a type
*
@@ -571,7 +531,7 @@ public abstract class GenericMetadataSupport {
*
* <p>If upper bounds are declared with SomeClass and additional interfaces, then firstBound will be SomeClass and
* interfacesBound will be an array of the additional interfaces.
- * <p>
+ *
* i.e. <code>SomeClass</code>.
* <pre class="code"><code class="java">
* interface UpperBoundedTypeWithClass<E extends Comparable<E> & Cloneable> {
diff --git a/src/main/java/org/mockito/internal/verification/VerificationWrapperInOrderWrapper.java b/src/main/java/org/mockito/internal/verification/VerificationWrapperInOrderWrapper.java
index 840efb7..eded985 100644
--- a/src/main/java/org/mockito/internal/verification/VerificationWrapperInOrderWrapper.java
+++ b/src/main/java/org/mockito/internal/verification/VerificationWrapperInOrderWrapper.java
@@ -47,7 +47,6 @@ public class VerificationWrapperInOrderWrapper implements VerificationMode {
}
}
- //TODO ugly exception message!!!
throw new MockitoException(verificationMode.getClass().getSimpleName() +
" is not implemented to work with InOrder wrapped inside a " +
verificationWrapper.getClass().getSimpleName());