diff options
Diffstat (limited to 'src/main/java/org/mockito')
11 files changed, 86 insertions, 10 deletions
diff --git a/src/main/java/org/mockito/ArgumentCaptor.java b/src/main/java/org/mockito/ArgumentCaptor.java index 1104de9..7011c92 100644 --- a/src/main/java/org/mockito/ArgumentCaptor.java +++ b/src/main/java/org/mockito/ArgumentCaptor.java @@ -49,7 +49,7 @@ import org.mockito.internal.matchers.CapturingMatcher; * Custom argument matchers via {@link ArgumentMatcher} are usually better for stubbing. * * <p> - * This utility class <strong>*don't do any type checks*</strong>, the generic signatures are only there to avoid casting + * This utility class <strong>*doesn't do any type checks*</strong>. The generic signatures are only there to avoid casting * in your code. * <p> * There is an <strong>annotation</strong> that you might find useful: @{@link Captor} @@ -136,7 +136,7 @@ public class ArgumentCaptor<T> { /** * Build a new <code>ArgumentCaptor</code>. * <p> - * Note that an <code>ArgumentCaptor</code> <b>*don't do any type checks*</b>, it is only there to avoid casting + * Note that an <code>ArgumentCaptor</code> <b>*doesn't do any type checks*</b>. It is only there to avoid casting * in your code. This might however change (type checks could be added) in a * future major release. * diff --git a/src/main/java/org/mockito/exceptions/misusing/InjectMocksException.java b/src/main/java/org/mockito/exceptions/misusing/InjectMocksException.java new file mode 100644 index 0000000..616d4b6 --- /dev/null +++ b/src/main/java/org/mockito/exceptions/misusing/InjectMocksException.java @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2018 Mockito contributors + * This program is made available under the terms of the MIT License. + */ +package org.mockito.exceptions.misusing; + +import org.mockito.exceptions.base.MockitoException; + +/** + * Thrown when creation of test subject annotated with InjectMocks fails. + */ +public class InjectMocksException extends MockitoException { + public InjectMocksException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/org/mockito/internal/creation/SuspendMethod.java b/src/main/java/org/mockito/internal/creation/SuspendMethod.java index 018bc50..42ceac6 100644 --- a/src/main/java/org/mockito/internal/creation/SuspendMethod.java +++ b/src/main/java/org/mockito/internal/creation/SuspendMethod.java @@ -11,12 +11,18 @@ 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_CONTINUATION = "kotlin.coroutines.experimental.Continuation"; + private static final String KOTLIN_EXPERIMENTAL_CONTINUATION = "kotlin.coroutines.experimental.Continuation"; + private static final String KOTLIN_CONTINUATION = "kotlin.coroutines.Continuation"; public static Class<?>[] trimSuspendParameterTypes(Class<?>[] parameterTypes) { int n = parameterTypes.length; - if (n > 0 && parameterTypes[n - 1].getName().equals(KOTLIN_CONTINUATION)) + if (n > 0 && isContinuationType(parameterTypes[n - 1])) 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/settings/CreationSettings.java b/src/main/java/org/mockito/internal/creation/settings/CreationSettings.java index 03afd80..81f52f9 100644 --- a/src/main/java/org/mockito/internal/creation/settings/CreationSettings.java +++ b/src/main/java/org/mockito/internal/creation/settings/CreationSettings.java @@ -57,6 +57,7 @@ public class CreationSettings<T> implements MockCreationSettings<T>, Serializabl 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/exceptions/Reporter.java b/src/main/java/org/mockito/internal/exceptions/Reporter.java index 2bc4445..38135a0 100644 --- a/src/main/java/org/mockito/internal/exceptions/Reporter.java +++ b/src/main/java/org/mockito/internal/exceptions/Reporter.java @@ -673,7 +673,7 @@ public class Reporter { } public static MockitoException fieldInitialisationThrewException(Field field, Throwable details) { - return new MockitoException(join( + return new InjectMocksException(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(), diff --git a/src/main/java/org/mockito/internal/framework/DefaultMockitoSession.java b/src/main/java/org/mockito/internal/framework/DefaultMockitoSession.java index c81baf2..c3f15f3 100644 --- a/src/main/java/org/mockito/internal/framework/DefaultMockitoSession.java +++ b/src/main/java/org/mockito/internal/framework/DefaultMockitoSession.java @@ -18,12 +18,10 @@ 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 { diff --git a/src/main/java/org/mockito/internal/junit/UniversalTestListener.java b/src/main/java/org/mockito/internal/junit/UniversalTestListener.java index 66c9dee..f670c64 100644 --- a/src/main/java/org/mockito/internal/junit/UniversalTestListener.java +++ b/src/main/java/org/mockito/internal/junit/UniversalTestListener.java @@ -5,6 +5,7 @@ package org.mockito.internal.junit; import org.mockito.internal.creation.settings.CreationSettings; +import org.mockito.internal.listeners.AutoCleanableListener; import org.mockito.internal.util.MockitoLogger; import org.mockito.mock.MockCreationSettings; import org.mockito.quality.Strictness; @@ -18,13 +19,14 @@ 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 { +public class UniversalTestListener implements MockitoTestListener, AutoCleanableListener { 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; @@ -85,4 +87,19 @@ public class UniversalTestListener implements MockitoTestListener { 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/listeners/AutoCleanableListener.java b/src/main/java/org/mockito/internal/listeners/AutoCleanableListener.java new file mode 100644 index 0000000..cfd2a53 --- /dev/null +++ b/src/main/java/org/mockito/internal/listeners/AutoCleanableListener.java @@ -0,0 +1,17 @@ +/* + * 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/progress/MockingProgressImpl.java b/src/main/java/org/mockito/internal/progress/MockingProgressImpl.java index 2685ddf..5c4fbbc 100644 --- a/src/main/java/org/mockito/internal/progress/MockingProgressImpl.java +++ b/src/main/java/org/mockito/internal/progress/MockingProgressImpl.java @@ -9,6 +9,7 @@ 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; @@ -19,6 +20,8 @@ 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; @@ -154,12 +157,28 @@ 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())) { - Reporter.redundantMockitoListener(listener.getClass().getSimpleName()); + 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()); + } } } - this.listeners.add(listener); + //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); } public void removeListener(MockitoListener listener) { diff --git a/src/main/java/org/mockito/internal/verification/VerificationWrapperInOrderWrapper.java b/src/main/java/org/mockito/internal/verification/VerificationWrapperInOrderWrapper.java index eded985..840efb7 100644 --- a/src/main/java/org/mockito/internal/verification/VerificationWrapperInOrderWrapper.java +++ b/src/main/java/org/mockito/internal/verification/VerificationWrapperInOrderWrapper.java @@ -47,6 +47,7 @@ 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()); diff --git a/src/main/java/org/mockito/plugins/InlineMockMaker.java b/src/main/java/org/mockito/plugins/InlineMockMaker.java index 8771aa7..ddc3ff6 100644 --- a/src/main/java/org/mockito/plugins/InlineMockMaker.java +++ b/src/main/java/org/mockito/plugins/InlineMockMaker.java @@ -50,3 +50,4 @@ public interface InlineMockMaker extends MockMaker { void clearAllMocks(); } + |