diff options
author | Philip P. Moltmann <moltmann@google.com> | 2018-08-28 16:38:37 +0000 |
---|---|---|
committer | Philip P. Moltmann <moltmann@google.com> | 2018-08-28 16:38:37 +0000 |
commit | 0a0255ce0b22e9660bef08a4c5041c7f6a9667c7 (patch) | |
tree | 0bf87e4d2caf0e63a07c8f5e22aef3d31ac6a82c /src/main/java/org/mockito | |
parent | 31b8dd0cbc0246fdab7ec2e9d1fd9fc822eac46d (diff) | |
download | mockito-0a0255ce0b22e9660bef08a4c5041c7f6a9667c7.tar.gz |
Revert "Update mockito on AOSP to same version as on internal master"
This reverts commit 31b8dd0cbc0246fdab7ec2e9d1fd9fc822eac46d.
Reason for revert: Breaks errorprone build
Change-Id: Iaf0e1154a109d435ade1b45b1518e178228bfb67
Diffstat (limited to 'src/main/java/org/mockito')
20 files changed, 102 insertions, 338 deletions
diff --git a/src/main/java/org/mockito/Mockito.java b/src/main/java/org/mockito/Mockito.java index 620b7d4..b25dae5 100644 --- a/src/main/java/org/mockito/Mockito.java +++ b/src/main/java/org/mockito/Mockito.java @@ -99,7 +99,6 @@ import org.mockito.verification.VerificationWithTimeout; * <a href="#42">42. (**new**) New API for integrations: listening on verification start events (Since 2.11.+)</a><br/> * <a href="#43">43. (**new**) New API for integrations: <code>MockitoSession</code> is usable by testing frameworks (Since 2.15.+)</a><br/> * <a href="#44">44. Deprecated <code>org.mockito.plugins.InstantiatorProvider</code> as it was leaking internal API. it was replaced by <code>org.mockito.plugins.InstantiatorProvider2 (Since 2.15.4)</code></a><br/> - * <a href="#45">45. (**new**) New JUnit Jupiter (JUnit5+) extension</a><br/> * </b> * * <h3 id="0">0. <a class="meaningful_link" href="#mockito2" name="mockito2">Migrating to Mockito 2</a></h3> @@ -1326,6 +1325,10 @@ import org.mockito.verification.VerificationWithTimeout; * Currently, the feature is still optional as we wait for more feedback from the community. * * <p> + * This feature is turned off by default because it is based on completely different mocking mechanism + * that requires more feedback from the community. + * + * <p> * This alternative mock maker which uses * a combination of both Java instrumentation API and sub-classing rather than creating a new class to represent * a mock. This way, it becomes possible to mock final types and methods. @@ -1503,11 +1506,6 @@ import org.mockito.verification.VerificationWithTimeout; * <p>{@link org.mockito.plugins.InstantiatorProvider} returned an internal API. Hence it was deprecated and replaced * by {@link org.mockito.plugins.InstantiatorProvider2}. Old {@link org.mockito.plugins.InstantiatorProvider * instantiator providers} will continue to work, but it is recommended to switch to the new API.</p> - * - * <h3 id="45">45. (**new**) <a class="meaningful_link" href="#junit5_mockito" name="junit5_mockito">New JUnit Jupiter (JUnit5+) extension</a></h3> - * - * For integration with JUnit Jupiter (JUnit5+), use the `org.mockito:mockito-junit-jupiter` artifact. - * For more information about the usage of the integration, see <a href="http://javadoc.io/page/org.mockito/mockito-junit-jupiter/latest/org/mockito/junit/jupiter/MockitoExtension.html">the JavaDoc of <code>MockitoExtension</code></a>. */ @SuppressWarnings("unchecked") public class Mockito extends ArgumentMatchers { @@ -1775,7 +1773,6 @@ public class Mockito extends ArgumentMatchers { * @param classToMock class or interface to mock * @return mock object */ - @CheckReturnValue public static <T> T mock(Class<T> classToMock) { return mock(classToMock, withSettings()); } @@ -1795,7 +1792,6 @@ public class Mockito extends ArgumentMatchers { * @param name of the mock * @return mock object */ - @CheckReturnValue public static <T> T mock(Class<T> classToMock, String name) { return mock(classToMock, withSettings() .name(name) @@ -1814,7 +1810,6 @@ public class Mockito extends ArgumentMatchers { * @return A {@link org.mockito.MockingDetails} instance. * @since 1.9.5 */ - @CheckReturnValue public static MockingDetails mockingDetails(Object toInspect) { return MOCKITO_CORE.mockingDetails(toInspect); } @@ -1838,7 +1833,6 @@ public class Mockito extends ArgumentMatchers { * * @return mock object */ - @CheckReturnValue public static <T> T mock(Class<T> classToMock, Answer defaultAnswer) { return mock(classToMock, withSettings().defaultAnswer(defaultAnswer)); } @@ -1866,7 +1860,6 @@ public class Mockito extends ArgumentMatchers { * @param mockSettings additional mock settings * @return mock object */ - @CheckReturnValue public static <T> T mock(Class<T> classToMock, MockSettings mockSettings) { return MOCKITO_CORE.mock(classToMock, mockSettings); } @@ -1950,7 +1943,6 @@ public class Mockito extends ArgumentMatchers { * to spy on * @return a spy of the real object */ - @CheckReturnValue public static <T> T spy(T object) { return MOCKITO_CORE.mock((Class<T>) object.getClass(), withSettings() .spiedInstance(object) @@ -1985,7 +1977,6 @@ public class Mockito extends ArgumentMatchers { * @since 1.10.12 */ @Incubating - @CheckReturnValue public static <T> T spy(Class<T> classToSpy) { return MOCKITO_CORE.mock(classToSpy, withSettings() .useConstructor() @@ -2530,7 +2521,6 @@ public class Mockito extends ArgumentMatchers { * * @return InOrder object to be used to verify in order */ - @CheckReturnValue public static InOrder inOrder(Object... mocks) { return MOCKITO_CORE.inOrder(mocks); } @@ -2614,7 +2604,6 @@ public class Mockito extends ArgumentMatchers { * * @return verification mode */ - @CheckReturnValue public static VerificationMode times(int wantedNumberOfInvocations) { return VerificationModeFactory.times(wantedNumberOfInvocations); } @@ -2636,7 +2625,6 @@ public class Mockito extends ArgumentMatchers { * * @return verification mode */ - @CheckReturnValue public static VerificationMode never() { return times(0); } @@ -2652,7 +2640,6 @@ public class Mockito extends ArgumentMatchers { * * @return verification mode */ - @CheckReturnValue public static VerificationMode atLeastOnce() { return VerificationModeFactory.atLeastOnce(); } @@ -2669,7 +2656,6 @@ public class Mockito extends ArgumentMatchers { * * @return verification mode */ - @CheckReturnValue public static VerificationMode atLeast(int minNumberOfInvocations) { return VerificationModeFactory.atLeast(minNumberOfInvocations); } @@ -2686,7 +2672,6 @@ public class Mockito extends ArgumentMatchers { * * @return verification mode */ - @CheckReturnValue public static VerificationMode atMost(int maxNumberOfInvocations) { return VerificationModeFactory.atMost(maxNumberOfInvocations); } @@ -2704,7 +2689,6 @@ public class Mockito extends ArgumentMatchers { * @param wantedNumberOfInvocations number of invocations to verify * @return verification mode */ - @CheckReturnValue public static VerificationMode calls( int wantedNumberOfInvocations ){ return VerificationModeFactory.calls( wantedNumberOfInvocations ); } @@ -2725,7 +2709,6 @@ public class Mockito extends ArgumentMatchers { * * @return verification mode */ - @CheckReturnValue public static VerificationMode only() { return VerificationModeFactory.only(); } @@ -2765,7 +2748,6 @@ public class Mockito extends ArgumentMatchers { * * @return verification mode */ - @CheckReturnValue public static VerificationWithTimeout timeout(long millis) { return new Timeout(millis, VerificationModeFactory.times(1)); } @@ -2806,7 +2788,6 @@ public class Mockito extends ArgumentMatchers { * * @return verification mode */ - @CheckReturnValue public static VerificationAfterDelay after(long millis) { return new After(millis, VerificationModeFactory.times(1)); } @@ -2890,7 +2871,6 @@ public class Mockito extends ArgumentMatchers { * * @return mock settings instance with defaults. */ - @CheckReturnValue public static MockSettings withSettings() { return new MockSettingsImpl().defaultAnswer(RETURNS_DEFAULTS); } @@ -2904,7 +2884,6 @@ public class Mockito extends ArgumentMatchers { * @return verification mode * @since 2.1.0 */ - @CheckReturnValue public static VerificationMode description(String description) { return times(1).description(description); } @@ -2914,7 +2893,6 @@ public class Mockito extends ArgumentMatchers { * An instance of {@code MockingDetails} can be retrieved via {@link #mockingDetails(Object)}. */ @Deprecated - @CheckReturnValue static MockitoDebugger debug() { return new MockitoDebuggerImpl(); } @@ -2925,7 +2903,6 @@ public class Mockito extends ArgumentMatchers { * @since 2.1.0 */ @Incubating - @CheckReturnValue public static MockitoFramework framework() { return new DefaultMockitoFramework(); } @@ -2939,7 +2916,6 @@ public class Mockito extends ArgumentMatchers { * @since 2.7.0 */ @Incubating - @CheckReturnValue public static MockitoSessionBuilder mockitoSession() { return new DefaultMockitoSessionBuilder(); } diff --git a/src/main/java/org/mockito/codegen/InjectionBase.java b/src/main/java/org/mockito/codegen/InjectionBase.java deleted file mode 100644 index b582c3b..0000000 --- a/src/main/java/org/mockito/codegen/InjectionBase.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2007 Mockito contributors - * This program is made available under the terms of the MIT License. - */ -package org.mockito.codegen; - -/** - * This class is required to resolve a method handle lookup for the {@code org.mockito.codegen} package what requires a preexisting class for the package. - * By defining this class, the JVM (starting from Java 9) assures that this package is a part of the Mockito module such that we gain full access rights. - */ -public class InjectionBase { - - private InjectionBase() { - throw new UnsupportedOperationException(); - } -} diff --git a/src/main/java/org/mockito/internal/configuration/SpyAnnotationEngine.java b/src/main/java/org/mockito/internal/configuration/SpyAnnotationEngine.java index 92d045d..a80efbe 100644 --- a/src/main/java/org/mockito/internal/configuration/SpyAnnotationEngine.java +++ b/src/main/java/org/mockito/internal/configuration/SpyAnnotationEngine.java @@ -140,7 +140,7 @@ public class SpyAnnotationEngine implements AnnotationEngine, org.mockito.config for (Class<? extends Annotation> u : undesiredAnnotations) { if (field.isAnnotationPresent(u)) { throw unsupportedCombinationOfAnnotations(annotation.getSimpleName(), - u.getSimpleName()); + annotation.getClass().getSimpleName()); } } } 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 71ae6a6..7d60f6c 100644 --- a/src/main/java/org/mockito/internal/creation/bytebuddy/InlineBytecodeGenerator.java +++ b/src/main/java/org/mockito/internal/creation/bytebuddy/InlineBytecodeGenerator.java @@ -15,7 +15,6 @@ import net.bytebuddy.description.method.MethodList; import net.bytebuddy.description.method.ParameterDescription; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.dynamic.ClassFileLocator; -import net.bytebuddy.dynamic.scaffold.MethodGraph; import net.bytebuddy.dynamic.scaffold.TypeValidation; import net.bytebuddy.implementation.Implementation; import net.bytebuddy.jar.asm.ClassVisitor; @@ -30,6 +29,7 @@ import org.mockito.internal.util.concurrent.WeakConcurrentSet; import org.mockito.mock.SerializableMode; import java.lang.instrument.ClassFileTransformer; +import java.lang.instrument.IllegalClassFormatException; import java.lang.instrument.Instrumentation; import java.lang.reflect.Modifier; import java.security.ProtectionDomain; @@ -44,8 +44,6 @@ import static org.mockito.internal.util.StringUtil.join; public class InlineBytecodeGenerator implements BytecodeGenerator, ClassFileTransformer { - private static final String PRELOAD = "org.mockito.inline.preload"; - @SuppressWarnings("unchecked") static final Set<Class<?>> EXCLUDES = new HashSet<Class<?>>(Arrays.asList(Class.class, Boolean.class, @@ -64,75 +62,34 @@ public class InlineBytecodeGenerator implements BytecodeGenerator, ClassFileTran private final WeakConcurrentSet<Class<?>> mocked; - private final BytecodeGenerator subclassEngine; + private final String identifier; - private final AsmVisitorWrapper mockTransformer; + private final MockMethodAdvice advice; + + private final BytecodeGenerator subclassEngine; private volatile Throwable lastException; public InlineBytecodeGenerator(Instrumentation instrumentation, WeakConcurrentMap<Object, MockMethodInterceptor> mocks) { - preload(); this.instrumentation = instrumentation; byteBuddy = new ByteBuddy() - .with(TypeValidation.DISABLED) - .with(Implementation.Context.Disabled.Factory.INSTANCE) - .with(MethodGraph.Compiler.ForDeclaredMethods.INSTANCE); + .with(TypeValidation.DISABLED) + .with(Implementation.Context.Disabled.Factory.INSTANCE); mocked = new WeakConcurrentSet<Class<?>>(WeakConcurrentSet.Cleaner.INLINE); - String identifier = RandomString.make(); + identifier = RandomString.make(); + advice = new MockMethodAdvice(mocks, identifier); subclassEngine = new TypeCachingBytecodeGenerator(new SubclassBytecodeGenerator(withDefaultConfiguration() - .withBinders(of(MockMethodAdvice.Identifier.class, identifier)) - .to(MockMethodAdvice.ForReadObject.class), isAbstract().or(isNative()).or(isToString())), false); - mockTransformer = new AsmVisitorWrapper.ForDeclaredMethods() - .method(isVirtual() - .and(not(isBridge().or(isHashCode()).or(isEquals()).or(isDefaultFinalizer()))) - .and(not(isDeclaredBy(nameStartsWith("java.")).<MethodDescription>and(isPackagePrivate()))), - Advice.withCustomMapping() - .bind(MockMethodAdvice.Identifier.class, identifier) - .to(MockMethodAdvice.class)) - .method(isHashCode(), - Advice.withCustomMapping() - .bind(MockMethodAdvice.Identifier.class, identifier) - .to(MockMethodAdvice.ForHashCode.class)) - .method(isEquals(), - Advice.withCustomMapping() - .bind(MockMethodAdvice.Identifier.class, identifier) - .to(MockMethodAdvice.ForEquals.class)); - MockMethodDispatcher.set(identifier, new MockMethodAdvice(mocks, identifier)); + .withBinders(of(MockMethodAdvice.Identifier.class, identifier)) + .to(MockMethodAdvice.ForReadObject.class), isAbstract().or(isNative()).or(isToString())), false); + MockMethodDispatcher.set(identifier, advice); instrumentation.addTransformer(this, true); } - /** - * Mockito allows to mock about any type, including such types that we are relying on ourselves. This can cause a circularity: - * In order to check if an instance is a mock we need to look up if this instance is registered in the {@code mocked} set. But to look - * up this instance, we need to create key instances that rely on weak reference properties. Loading the later classes will happen before - * the key instances are completed what will cause Mockito to check if those key instances are themselves mocks what causes a loop which - * results in a circularity error. This is not normally a problem as we explicitly check if the instance that we investigate is one of - * our instance of which we hold a reference by reference equality what does not cause any code execution. But it seems like the load - * order plays a role here with unloaded types being loaded before we even get to check the mock instance property. To avoid this, we are - * making sure that crucuial JVM types are loaded before we create the first inline mock. Unfortunately, these types dependant on a JVM's - * implementation and we can only maintain types that we know of from well-known JVM implementations such as HotSpot and extend this list - * once we learn of further problematic types for future Java versions. To allow users to whitelist their own types, we do not also offer - * a property that allows running problematic tests before a new Mockito version can be released and that allows us to ask users to - * easily validate that whitelisting actually solves a problem as circularities could also be caused by other problems. - */ - private static void preload() { - String preloads = System.getProperty(PRELOAD); - if (preloads == null) { - preloads = "java.lang.WeakPairMap,java.lang.WeakPairMap$Pair,java.lang.WeakPairMap$Pair$Weak"; - } - for (String preload : preloads.split(",")) { - try { - Class.forName(preload, false, null); - } catch (ClassNotFoundException ignored) { - } - } - } - @Override public <T> Class<? extends T> mockClass(MockFeatures<T> features) { boolean subclassingRequired = !features.interfaces.isEmpty() - || features.serializableMode != SerializableMode.NONE - || Modifier.isAbstract(features.mockedType.getModifiers()); + || features.serializableMode != SerializableMode.NONE + || Modifier.isAbstract(features.mockedType.getModifiers()); checkSupportedCombination(subclassingRequired, features); @@ -200,19 +157,29 @@ public class InlineBytecodeGenerator implements BytecodeGenerator, ClassFileTran String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, - byte[] classfileBuffer) { + byte[] classfileBuffer) throws IllegalClassFormatException { if (classBeingRedefined == null - || !mocked.contains(classBeingRedefined) - || EXCLUDES.contains(classBeingRedefined)) { + || !mocked.contains(classBeingRedefined) + || EXCLUDES.contains(classBeingRedefined)) { return null; } else { try { return byteBuddy.redefine(classBeingRedefined, ClassFileLocator.Simple.of(classBeingRedefined.getName(), classfileBuffer)) - // Note: The VM erases parameter meta data from the provided class file (bug). We just add this information manually. - .visit(new ParameterWritingVisitorWrapper(classBeingRedefined)) - .visit(mockTransformer) - .make() - .getBytes(); + // Note: The VM erases parameter meta data from the provided class file (bug). We just add this information manually. + .visit(new ParameterWritingVisitorWrapper(classBeingRedefined)) + .visit(Advice.withCustomMapping() + .bind(MockMethodAdvice.Identifier.class, identifier) + .to(MockMethodAdvice.class).on(isVirtual() + .and(not(isBridge().or(isHashCode()).or(isEquals()).or(isDefaultFinalizer()))) + .and(not(isDeclaredBy(nameStartsWith("java.")).<MethodDescription>and(isPackagePrivate()))))) + .visit(Advice.withCustomMapping() + .bind(MockMethodAdvice.Identifier.class, identifier) + .to(MockMethodAdvice.ForHashCode.class).on(isHashCode())) + .visit(Advice.withCustomMapping() + .bind(MockMethodAdvice.Identifier.class, identifier) + .to(MockMethodAdvice.ForEquals.class).on(isEquals())) + .make() + .getBytes(); } catch (Throwable throwable) { lastException = throwable; return null; @@ -247,7 +214,7 @@ public class InlineBytecodeGenerator implements BytecodeGenerator, ClassFileTran private final TypeDescription typeDescription; private ParameterAddingClassVisitor(ClassVisitor cv, TypeDescription typeDescription) { - super(Opcodes.ASM6, cv); + super(Opcodes.ASM5, cv); this.typeDescription = typeDescription; } 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 b659c73..dc5c6e5 100644 --- a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassBytecodeGenerator.java +++ b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassBytecodeGenerator.java @@ -38,8 +38,6 @@ import static org.mockito.internal.util.StringUtil.join; class SubclassBytecodeGenerator implements BytecodeGenerator { - private static final String CODEGEN_PACKAGE = "org.mockito.codegen."; - private final SubclassLoader loader; private final ByteBuddy byteBuddy; @@ -48,11 +46,6 @@ class SubclassBytecodeGenerator implements BytecodeGenerator { private final Implementation readReplace; private final ElementMatcher<? super MethodDescription> matcher; - private final Implementation dispatcher = to(DispatcherDefaultingToRealMethod.class); - private final Implementation hashCode = to(MockMethodInterceptor.ForHashCode.class); - private final Implementation equals = to(MockMethodInterceptor.ForEquals.class); - private final Implementation writeReplace = to(MockMethodInterceptor.ForWriteReplace.class); - public SubclassBytecodeGenerator() { this(new SubclassInjectionLoader()); } @@ -75,32 +68,31 @@ class SubclassBytecodeGenerator implements BytecodeGenerator { @Override public <T> Class<? extends T> mockClass(MockFeatures<T> features) { - String name = nameFor(features.mockedType); DynamicType.Builder<T> builder = byteBuddy.subclass(features.mockedType) - .name(name) + .name(nameFor(features.mockedType)) .ignoreAlso(isGroovyMethod()) .annotateType(features.stripAnnotations ? new Annotation[0] : features.mockedType.getAnnotations()) .implement(new ArrayList<Type>(features.interfaces)) .method(matcher) - .intercept(dispatcher) + .intercept(to(DispatcherDefaultingToRealMethod.class)) .transform(withModifiers(SynchronizationState.PLAIN)) .attribute(features.stripAnnotations ? MethodAttributeAppender.NoOp.INSTANCE : INCLUDING_RECEIVER) .method(isHashCode()) - .intercept(hashCode) + .intercept(to(MockMethodInterceptor.ForHashCode.class)) .method(isEquals()) - .intercept(equals) + .intercept(to(MockMethodInterceptor.ForEquals.class)) .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(to(MockMethodInterceptor.ForWriteReplace.class)); } if (readReplace != null) { builder = builder.defineMethod("readObject", void.class, Visibility.PRIVATE) @@ -126,7 +118,7 @@ class SubclassBytecodeGenerator implements BytecodeGenerator { .or(hasParameters(whereAny(hasType(isPackagePrivate()))))); } return builder.make() - .load(classLoader, loader.resolveStrategy(features.mockedType, classLoader, name.startsWith(CODEGEN_PACKAGE))) + .load(classLoader, loader.getStrategy(features.mockedType)) .getLoaded(); } @@ -140,7 +132,7 @@ class SubclassBytecodeGenerator implements BytecodeGenerator { if (isComingFromJDK(type) || isComingFromSignedJar(type) || isComingFromSealedPackage(type)) { - typeName = CODEGEN_PACKAGE + type.getSimpleName(); + typeName = "codegen." + typeName; } return String.format("%s$%s$%d", typeName, "MockitoMock", Math.abs(random.nextInt())); } 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 454dd8e..20125f1 100644 --- a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassInjectionLoader.java +++ b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassInjectionLoader.java @@ -4,104 +4,12 @@ */ package org.mockito.internal.creation.bytebuddy; -import net.bytebuddy.dynamic.loading.ClassInjector; import net.bytebuddy.dynamic.loading.ClassLoadingStrategy; -import org.mockito.codegen.InjectionBase; -import org.mockito.exceptions.base.MockitoException; -import org.mockito.internal.util.Platform; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import static org.mockito.internal.util.StringUtil.join; class SubclassInjectionLoader implements SubclassLoader { - private static final String ERROR_MESSAGE = join("The current JVM does not support any class injection mechanism.", - "", - "Currently, Mockito supports injection via neither by method handle lookups or using sun.misc.Unsafe", - "Neither seems to be available on your current JVM."); - - private final SubclassLoader loader; - - SubclassInjectionLoader() { - if (!Boolean.getBoolean("org.mockito.internal.simulateJava11") && ClassInjector.UsingReflection.isAvailable()) { - this.loader = new WithReflection(); - } else if (ClassInjector.UsingLookup.isAvailable()) { - this.loader = tryLookup(); - } else { - throw new MockitoException(join(ERROR_MESSAGE, "", Platform.describe())); - } - } - - private static SubclassLoader tryLookup() { - try { - Class<?> methodHandles = Class.forName("java.lang.invoke.MethodHandles"); - Object lookup = methodHandles.getMethod("lookup").invoke(null); - Method privateLookupIn = methodHandles.getMethod("privateLookupIn", Class.class, Class.forName("java.lang.invoke.MethodHandles$Lookup")); - Object codegenLookup = privateLookupIn.invoke(null, InjectionBase.class, lookup); - return new WithLookup(lookup, codegenLookup, privateLookupIn); - } catch (Exception exception) { - throw new MockitoException(join(ERROR_MESSAGE, "", Platform.describe()), exception); - } - } - - private static class WithReflection implements SubclassLoader { - - @Override - public ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean codegen) { - return ClassLoadingStrategy.Default.INJECTION.with(codegen ? InjectionBase.class.getProtectionDomain() : mockedType.getProtectionDomain()); - } - } - - private static class WithLookup implements SubclassLoader { - - private final Object lookup; - - private final Object codegenLookup; - - private final Method privateLookupIn; - - WithLookup(Object lookup, Object codegenLookup, Method privateLookupIn) { - this.lookup = lookup; - this.codegenLookup = codegenLookup; - this.privateLookupIn = privateLookupIn; - } - - @Override - 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 { - privateLookup = privateLookupIn.invoke(null, mockedType, lookup); - } catch (InvocationTargetException exception) { - if (exception.getCause() instanceof IllegalAccessException) { - return ClassLoadingStrategy.Default.WRAPPER.with(mockedType.getProtectionDomain()); - } else { - throw exception.getCause(); - } - } - return ClassLoadingStrategy.UsingLookup.of(privateLookup); - } catch (Throwable exception) { - throw new MockitoException(join( - "The Java module system prevents Mockito from defining a mock class in the same package as " + mockedType, - "", - "To overcome this, you must open and export the mocked type to Mockito.", - "Remember that you can also do so programmatically if the mocked class is defined by the same module as your test code", - exception - )); - } - } - } - } - @Override - public ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean codegen) { - return loader.resolveStrategy(mockedType, classLoader, codegen); + public ClassLoadingStrategy<ClassLoader> getStrategy(Class<?> mockedType) { + return ClassLoadingStrategy.Default.INJECTION.with(mockedType.getProtectionDomain()); } } 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 194c282..80b17ac 100644 --- a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassLoader.java +++ b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassLoader.java @@ -6,18 +6,8 @@ package org.mockito.internal.creation.bytebuddy; import net.bytebuddy.dynamic.loading.ClassLoadingStrategy; -/** - * A subclass loader is responsible for resolving a class loading strategy for a mock that is implemented as a subclass. - */ public interface SubclassLoader { - /** - * Resolves a class loading strategy. - * - * @param mockedType The type being mocked. - * @param classLoader The class loader being used. - * @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 codegen); + ClassLoadingStrategy<ClassLoader> getStrategy(Class<?> mockedType); + } diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/TypeCachingBytecodeGenerator.java b/src/main/java/org/mockito/internal/creation/bytebuddy/TypeCachingBytecodeGenerator.java index ea51edf..34c31fe 100644 --- a/src/main/java/org/mockito/internal/creation/bytebuddy/TypeCachingBytecodeGenerator.java +++ b/src/main/java/org/mockito/internal/creation/bytebuddy/TypeCachingBytecodeGenerator.java @@ -36,7 +36,7 @@ class TypeCachingBytecodeGenerator extends ReferenceQueue<ClassLoader> implement public Class<?> call() throws Exception { return bytecodeGenerator.mockClass(params); } - }, BOOTSTRAP_LOCK); + }, classLoader == null ? BOOTSTRAP_LOCK : classLoader); } catch (IllegalArgumentException exception) { Throwable cause = exception.getCause(); if (cause instanceof RuntimeException) { diff --git a/src/main/java/org/mockito/internal/exceptions/Reporter.java b/src/main/java/org/mockito/internal/exceptions/Reporter.java index 17823ff..57094c0 100644 --- a/src/main/java/org/mockito/internal/exceptions/Reporter.java +++ b/src/main/java/org/mockito/internal/exceptions/Reporter.java @@ -5,27 +5,9 @@ package org.mockito.internal.exceptions; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; import org.mockito.exceptions.base.MockitoAssertionError; import org.mockito.exceptions.base.MockitoException; -import org.mockito.exceptions.misusing.CannotStubVoidMethodWithReturnValue; -import org.mockito.exceptions.misusing.CannotVerifyStubOnlyMock; -import org.mockito.exceptions.misusing.FriendlyReminderException; -import org.mockito.exceptions.misusing.InvalidUseOfMatchersException; -import org.mockito.exceptions.misusing.MissingMethodInvocationException; -import org.mockito.exceptions.misusing.NotAMockException; -import org.mockito.exceptions.misusing.NullInsteadOfMockException; -import org.mockito.exceptions.misusing.PotentialStubbingProblem; -import org.mockito.exceptions.misusing.RedundantListenerException; -import org.mockito.exceptions.misusing.UnfinishedMockingSessionException; -import org.mockito.exceptions.misusing.UnfinishedStubbingException; -import org.mockito.exceptions.misusing.UnfinishedVerificationException; -import org.mockito.exceptions.misusing.UnnecessaryStubbingException; -import org.mockito.exceptions.misusing.WrongTypeOfReturnValue; +import org.mockito.exceptions.misusing.*; import org.mockito.exceptions.verification.NeverWantedButInvoked; import org.mockito.exceptions.verification.NoInteractionsWanted; import org.mockito.exceptions.verification.SmartNullPointerException; @@ -46,6 +28,12 @@ import org.mockito.listeners.InvocationListener; import org.mockito.mock.MockName; import org.mockito.mock.SerializableMode; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + import static org.mockito.internal.reporting.Pluralizer.pluralize; import static org.mockito.internal.reporting.Pluralizer.were_exactly_x_interactions; import static org.mockito.internal.util.StringUtil.join; @@ -370,71 +358,63 @@ public class Reporter { )); } - public static MockitoAssertionError tooManyActualInvocations(int wantedCount, int actualCount, DescribedInvocation wanted, List<Location> locations) { - String message = createTooManyInvocationsMessage(wantedCount, actualCount, wanted, locations); + public static MockitoAssertionError tooManyActualInvocations(int wantedCount, int actualCount, DescribedInvocation wanted, Location firstUndesired) { + String message = createTooManyInvocationsMessage(wantedCount, actualCount, wanted, firstUndesired); return new TooManyActualInvocations(message); } private static String createTooManyInvocationsMessage(int wantedCount, int actualCount, DescribedInvocation wanted, - List<Location> invocations) { + Location firstUndesired) { return join( wanted.toString(), "Wanted " + pluralize(wantedCount) + ":", new LocationImpl(), - "But was " + pluralize(actualCount) + ":", - createAllLocationsMessage(invocations), + "But was " + pluralize(actualCount) + ". Undesired invocation:", + firstUndesired, "" ); } - public static MockitoAssertionError neverWantedButInvoked(DescribedInvocation wanted, List<Location> invocations) { + public static MockitoAssertionError neverWantedButInvoked(DescribedInvocation wanted, Location firstUndesired) { return new NeverWantedButInvoked(join( wanted.toString(), "Never wanted here:", new LocationImpl(), "But invoked here:", - createAllLocationsMessage(invocations) + firstUndesired, + "" )); } - public static MockitoAssertionError tooManyActualInvocationsInOrder(int wantedCount, int actualCount, DescribedInvocation wanted, List<Location> invocations) { - String message = createTooManyInvocationsMessage(wantedCount, actualCount, wanted, invocations); + public static MockitoAssertionError tooManyActualInvocationsInOrder(int wantedCount, int actualCount, DescribedInvocation wanted, Location firstUndesired) { + String message = createTooManyInvocationsMessage(wantedCount, actualCount, wanted, firstUndesired); return new VerificationInOrderFailure(join( "Verification in order failure:" + message )); } - private static String createAllLocationsMessage(List<Location> locations) { - if (locations == null) { - return "\n"; - } - StringBuilder sb = new StringBuilder(); - for (Location location : locations) { - sb.append(location).append("\n"); - } - return sb.toString(); - } + private static String createTooLittleInvocationsMessage(org.mockito.internal.reporting.Discrepancy discrepancy, DescribedInvocation wanted, + Location lastActualInvocation) { + String ending = + (lastActualInvocation != null) ? lastActualInvocation + "\n" : "\n"; - private static String createTooLittleInvocationsMessage(org.mockito.internal.reporting.Discrepancy discrepancy, - DescribedInvocation wanted, - List<Location> locations) { return join( wanted.toString(), "Wanted " + discrepancy.getPluralizedWantedCount() + (discrepancy.getWantedCount() == 0 ? "." : ":"), new LocationImpl(), "But was " + discrepancy.getPluralizedActualCount() + (discrepancy.getActualCount() == 0 ? "." : ":"), - createAllLocationsMessage(locations) + ending ); } - public static MockitoAssertionError tooLittleActualInvocations(org.mockito.internal.reporting.Discrepancy discrepancy, DescribedInvocation wanted, List<Location> allLocations) { - String message = createTooLittleInvocationsMessage(discrepancy, wanted, allLocations); + public static MockitoAssertionError tooLittleActualInvocations(org.mockito.internal.reporting.Discrepancy discrepancy, DescribedInvocation wanted, Location lastActualLocation) { + String message = createTooLittleInvocationsMessage(discrepancy, wanted, lastActualLocation); return new TooLittleActualInvocations(message); } - public static MockitoAssertionError tooLittleActualInvocationsInOrder(org.mockito.internal.reporting.Discrepancy discrepancy, DescribedInvocation wanted, List<Location> locations) { - String message = createTooLittleInvocationsMessage(discrepancy, wanted, locations); + public static MockitoAssertionError tooLittleActualInvocationsInOrder(org.mockito.internal.reporting.Discrepancy discrepancy, DescribedInvocation wanted, Location lastActualLocation) { + String message = createTooLittleInvocationsMessage(discrepancy, wanted, lastActualLocation); return new VerificationInOrderFailure(join( "Verification in order failure:" + message diff --git a/src/main/java/org/mockito/internal/hamcrest/HamcrestArgumentMatcher.java b/src/main/java/org/mockito/internal/hamcrest/HamcrestArgumentMatcher.java index 9892422..f5216ee 100644 --- a/src/main/java/org/mockito/internal/hamcrest/HamcrestArgumentMatcher.java +++ b/src/main/java/org/mockito/internal/hamcrest/HamcrestArgumentMatcher.java @@ -7,7 +7,6 @@ package org.mockito.internal.hamcrest; import org.hamcrest.Matcher; import org.hamcrest.StringDescription; import org.mockito.ArgumentMatcher; -import org.mockito.internal.matchers.VarargMatcher; public class HamcrestArgumentMatcher<T> implements ArgumentMatcher<T> { @@ -21,10 +20,6 @@ public class HamcrestArgumentMatcher<T> implements ArgumentMatcher<T> { return this.matcher.matches(argument); } - public boolean isVarargMatcher() { - return matcher instanceof VarargMatcher; - } - public String toString() { //TODO SF add unit tests and integ test coverage for describeTo() return StringDescription.toString(matcher); diff --git a/src/main/java/org/mockito/internal/invocation/InvocationsFinder.java b/src/main/java/org/mockito/internal/invocation/InvocationsFinder.java index 260321b..57c335f 100644 --- a/src/main/java/org/mockito/internal/invocation/InvocationsFinder.java +++ b/src/main/java/org/mockito/internal/invocation/InvocationsFinder.java @@ -138,14 +138,6 @@ public class InvocationsFinder { return unverified; } - public static List<Location> getAllLocations(List<Invocation> invocations) { - List<Location> locations = new LinkedList<Location>(); - for (Invocation invocation : invocations) { - locations.add(invocation.getLocation()); - } - return locations; - } - private static class RemoveNotMatching implements Filter<Invocation> { private final MatchableInvocation wanted; diff --git a/src/main/java/org/mockito/internal/invocation/MatcherApplicationStrategy.java b/src/main/java/org/mockito/internal/invocation/MatcherApplicationStrategy.java index e47156f..e085c25 100644 --- a/src/main/java/org/mockito/internal/invocation/MatcherApplicationStrategy.java +++ b/src/main/java/org/mockito/internal/invocation/MatcherApplicationStrategy.java @@ -12,7 +12,6 @@ import java.util.ArrayList; import java.util.List; import org.mockito.ArgumentMatcher; -import org.mockito.internal.hamcrest.HamcrestArgumentMatcher; import org.mockito.internal.matchers.CapturingMatcher; import org.mockito.internal.matchers.VarargMatcher; import org.mockito.invocation.Invocation; @@ -96,19 +95,15 @@ public class MatcherApplicationStrategy { return ONE_MATCHER_PER_ARGUMENT; } - if (rawArguments == matcherCount && isLastMatcherVarargMatcher(matchers)) { + if (rawArguments == matcherCount && isLastMatcherVargargMatcher(matchers)) { return MATCH_EACH_VARARGS_WITH_LAST_MATCHER; } return ERROR_UNSUPPORTED_NUMBER_OF_MATCHERS; } - private static boolean isLastMatcherVarargMatcher(final List<ArgumentMatcher<?>> matchers) { - ArgumentMatcher<?> argumentMatcher = lastMatcher(matchers); - if (argumentMatcher instanceof HamcrestArgumentMatcher<?>) { - return ((HamcrestArgumentMatcher<?>) argumentMatcher).isVarargMatcher(); - } - return argumentMatcher instanceof VarargMatcher; + private static boolean isLastMatcherVargargMatcher(final List<ArgumentMatcher<?>> matchers) { + return lastMatcher(matchers) instanceof VarargMatcher; } private static List<ArgumentMatcher<?>> appendLastMatcherNTimes(List<ArgumentMatcher<?>> matchers, int timesToAppendLastMatcher) { diff --git a/src/main/java/org/mockito/internal/stubbing/BaseStubbing.java b/src/main/java/org/mockito/internal/stubbing/BaseStubbing.java index 6dd99cd..ddb9a8d 100644 --- a/src/main/java/org/mockito/internal/stubbing/BaseStubbing.java +++ b/src/main/java/org/mockito/internal/stubbing/BaseStubbing.java @@ -24,8 +24,7 @@ public abstract class BaseStubbing<T> implements OngoingStubbing<T> { public OngoingStubbing<T> thenReturn(T value, T... values) { OngoingStubbing<T> stubbing = thenReturn(value); if (values == null) { - // For no good reason we're configuring null answer here - // This has been like that since forever, so let's keep it for compatibility (unless users complain) + // TODO below does not seem right return stubbing.thenReturn(null); } for (T v : values) { @@ -66,7 +65,7 @@ public abstract class BaseStubbing<T> implements OngoingStubbing<T> { @Override public OngoingStubbing<T> thenThrow(Class<? extends Throwable> toBeThrown, Class<? extends Throwable>... nextToBeThrown) { if (nextToBeThrown == null) { - return thenThrow((Class<Throwable>) null); + thenThrow((Class<Throwable>) null); } OngoingStubbing<T> stubbing = thenThrow(toBeThrown); for (Class<? extends Throwable> t : nextToBeThrown) { diff --git a/src/main/java/org/mockito/internal/stubbing/StubberImpl.java b/src/main/java/org/mockito/internal/stubbing/StubberImpl.java index 7771c04..b18d05d 100644 --- a/src/main/java/org/mockito/internal/stubbing/StubberImpl.java +++ b/src/main/java/org/mockito/internal/stubbing/StubberImpl.java @@ -83,9 +83,9 @@ public class StubberImpl implements Stubber { Throwable e; try { e = newInstance(toBeThrown); - } catch (RuntimeException instantiationError) { + } catch (RuntimeException instanciationError) { mockingProgress().reset(); - throw instantiationError; + throw instanciationError; } return doThrow(e); } diff --git a/src/main/java/org/mockito/internal/stubbing/answers/ThrowsException.java b/src/main/java/org/mockito/internal/stubbing/answers/ThrowsException.java index 502e359..037520f 100644 --- a/src/main/java/org/mockito/internal/stubbing/answers/ThrowsException.java +++ b/src/main/java/org/mockito/internal/stubbing/answers/ThrowsException.java @@ -14,36 +14,23 @@ import org.mockito.stubbing.ValidableAnswer; import static org.mockito.internal.exceptions.Reporter.cannotStubWithNullThrowable; import static org.mockito.internal.exceptions.Reporter.checkedExceptionInvalid; -/** - * An answer that always throws the same throwable. - */ public class ThrowsException implements Answer<Object>, ValidableAnswer, Serializable { private static final long serialVersionUID = 1128820328555183980L; private final Throwable throwable; private final ConditionalStackTraceFilter filter = new ConditionalStackTraceFilter(); - /** - * Creates a new answer always throwing the given throwable. If it is null, - * {@linkplain ValidableAnswer#validateFor(InvocationOnMock) answer validation} - * will fail. - */ public ThrowsException(Throwable throwable) { this.throwable = throwable; } public Object answer(InvocationOnMock invocation) throws Throwable { - if (throwable == null) { - throw new IllegalStateException("throwable is null: " + - "you shall not call #answer if #validateFor fails!"); - } if (MockUtil.isMock(throwable)) { throw throwable; } Throwable t = throwable.fillInStackTrace(); if (t == null) { - //Custom exceptions sometimes return null, see #866 throw throwable; } filter.filter(t); diff --git a/src/main/java/org/mockito/internal/util/Primitives.java b/src/main/java/org/mockito/internal/util/Primitives.java index 80dd0af..4d813e3 100644 --- a/src/main/java/org/mockito/internal/util/Primitives.java +++ b/src/main/java/org/mockito/internal/util/Primitives.java @@ -44,7 +44,7 @@ public class Primitives { public static boolean isAssignableFromWrapper(Class<?> valueClass, Class<?> referenceType) { if(isPrimitiveOrWrapper(valueClass) && isPrimitiveOrWrapper(referenceType)) { - return Primitives.primitiveTypeOf(valueClass).isAssignableFrom(Primitives.primitiveTypeOf(referenceType)); + return Primitives.primitiveTypeOf(valueClass).isAssignableFrom(referenceType); } return false; } diff --git a/src/main/java/org/mockito/internal/util/concurrent/WeakConcurrentMap.java b/src/main/java/org/mockito/internal/util/concurrent/WeakConcurrentMap.java index 487d223..b411a73 100644 --- a/src/main/java/org/mockito/internal/util/concurrent/WeakConcurrentMap.java +++ b/src/main/java/org/mockito/internal/util/concurrent/WeakConcurrentMap.java @@ -50,7 +50,6 @@ public class WeakConcurrentMap<K, V> extends ReferenceQueue<K> implements Runnab * @param key The key of the entry. * @return The value of the entry or the default value if it did not exist. */ - @SuppressWarnings("CollectionIncompatibleType") public V get(K key) { if (key == null) throw new NullPointerException(); V value = target.get(new LatentKey<K>(key)); @@ -70,7 +69,6 @@ public class WeakConcurrentMap<K, V> extends ReferenceQueue<K> implements Runnab * @param key The key of the entry. * @return {@code true} if the key already defines a value. */ - @SuppressWarnings("CollectionIncompatibleType") public boolean containsKey(K key) { if (key == null) throw new NullPointerException(); return target.containsKey(new LatentKey<K>(key)); @@ -90,7 +88,6 @@ public class WeakConcurrentMap<K, V> extends ReferenceQueue<K> implements Runnab * @param key The key of the entry. * @return The removed entry or {@code null} if it does not exist. */ - @SuppressWarnings("CollectionIncompatibleType") public V remove(K key) { if (key == null) throw new NullPointerException(); return target.remove(new LatentKey<K>(key)); diff --git a/src/main/java/org/mockito/internal/verification/checkers/AtLeastXNumberOfInvocationsChecker.java b/src/main/java/org/mockito/internal/verification/checkers/AtLeastXNumberOfInvocationsChecker.java index d0eb0b5..36e35a3 100644 --- a/src/main/java/org/mockito/internal/verification/checkers/AtLeastXNumberOfInvocationsChecker.java +++ b/src/main/java/org/mockito/internal/verification/checkers/AtLeastXNumberOfInvocationsChecker.java @@ -17,7 +17,7 @@ import static org.mockito.internal.invocation.InvocationMarker.markVerified; import static org.mockito.internal.invocation.InvocationMarker.markVerifiedInOrder; import static org.mockito.internal.invocation.InvocationsFinder.findAllMatchingUnverifiedChunks; import static org.mockito.internal.invocation.InvocationsFinder.findInvocations; -import static org.mockito.internal.invocation.InvocationsFinder.getAllLocations; +import static org.mockito.internal.invocation.InvocationsFinder.getLastLocation; public class AtLeastXNumberOfInvocationsChecker { @@ -26,8 +26,8 @@ public class AtLeastXNumberOfInvocationsChecker { int actualCount = actualInvocations.size(); if (wantedCount > actualCount) { - List<Location> allLocations = getAllLocations(actualInvocations); - throw tooLittleActualInvocations(new AtLeastDiscrepancy(wantedCount, actualCount), wanted, allLocations); + Location lastLocation = getLastLocation(actualInvocations); + throw tooLittleActualInvocations(new AtLeastDiscrepancy(wantedCount, actualCount), wanted, lastLocation); } markVerified(actualInvocations, wanted); @@ -39,8 +39,8 @@ public class AtLeastXNumberOfInvocationsChecker { int actualCount = chunk.size(); if (wantedCount > actualCount) { - List<Location> allLocations = getAllLocations(chunk); - throw tooLittleActualInvocationsInOrder(new AtLeastDiscrepancy(wantedCount, actualCount), wanted, allLocations); + Location lastLocation = getLastLocation(chunk); + throw tooLittleActualInvocationsInOrder(new AtLeastDiscrepancy(wantedCount, actualCount), wanted, lastLocation); } markVerifiedInOrder(chunk, wanted, orderingContext); diff --git a/src/main/java/org/mockito/internal/verification/checkers/NumberOfInvocationsChecker.java b/src/main/java/org/mockito/internal/verification/checkers/NumberOfInvocationsChecker.java index 1dfc2f1..3fa340f 100644 --- a/src/main/java/org/mockito/internal/verification/checkers/NumberOfInvocationsChecker.java +++ b/src/main/java/org/mockito/internal/verification/checkers/NumberOfInvocationsChecker.java @@ -5,7 +5,6 @@ package org.mockito.internal.verification.checkers; -import java.util.Arrays; import java.util.List; import org.mockito.internal.reporting.Discrepancy; import org.mockito.internal.verification.api.InOrderContext; @@ -23,7 +22,7 @@ import static org.mockito.internal.invocation.InvocationMarker.markVerifiedInOrd import static org.mockito.internal.invocation.InvocationsFinder.findFirstMatchingUnverifiedInvocation; import static org.mockito.internal.invocation.InvocationsFinder.findInvocations; import static org.mockito.internal.invocation.InvocationsFinder.findMatchingChunk; -import static org.mockito.internal.invocation.InvocationsFinder.getAllLocations; +import static org.mockito.internal.invocation.InvocationsFinder.getLastLocation; public class NumberOfInvocationsChecker { @@ -35,14 +34,16 @@ public class NumberOfInvocationsChecker { int actualCount = actualInvocations.size(); if (wantedCount > actualCount) { - List<Location> allLocations = getAllLocations(actualInvocations); - throw tooLittleActualInvocations(new Discrepancy(wantedCount, actualCount), wanted, allLocations); + Location lastInvocation = getLastLocation(actualInvocations); + throw tooLittleActualInvocations(new Discrepancy(wantedCount, actualCount), wanted, lastInvocation); } if (wantedCount == 0 && actualCount > 0) { - throw neverWantedButInvoked(wanted, getAllLocations(actualInvocations)); + Location firstUndesired = actualInvocations.get(wantedCount).getLocation(); + throw neverWantedButInvoked(wanted, firstUndesired); } if (wantedCount < actualCount) { - throw tooManyActualInvocations(wantedCount, actualCount, wanted, getAllLocations(actualInvocations)); + Location firstUndesired = actualInvocations.get(wantedCount).getLocation(); + throw tooManyActualInvocations(wantedCount, actualCount, wanted, firstUndesired); } markVerified(actualInvocations, wanted); @@ -54,11 +55,12 @@ public class NumberOfInvocationsChecker { int actualCount = chunk.size(); if (wantedCount > actualCount) { - List<Location> allLocations = getAllLocations(chunk); - throw tooLittleActualInvocationsInOrder(new Discrepancy(wantedCount, actualCount), wanted, allLocations); + Location lastInvocation = getLastLocation(chunk); + throw tooLittleActualInvocationsInOrder(new Discrepancy(wantedCount, actualCount), wanted, lastInvocation); } if (wantedCount < actualCount) { - throw tooManyActualInvocationsInOrder(wantedCount, actualCount, wanted, getAllLocations(chunk)); + Location firstUndesired = chunk.get(wantedCount).getLocation(); + throw tooManyActualInvocationsInOrder(wantedCount, actualCount, wanted, firstUndesired); } markVerifiedInOrder(chunk, wanted, context); @@ -70,7 +72,7 @@ public class NumberOfInvocationsChecker { while( actualCount < wantedCount ){ Invocation next = findFirstMatchingUnverifiedInvocation(invocations, wanted, context ); if( next == null ){ - throw tooLittleActualInvocationsInOrder(new Discrepancy(wantedCount, actualCount), wanted, Arrays.asList(lastLocation)); + throw tooLittleActualInvocationsInOrder(new Discrepancy(wantedCount, actualCount), wanted, lastLocation ); } markVerified( next, wanted ); context.markVerified( next ); diff --git a/src/main/java/org/mockito/session/MockitoSessionBuilder.java b/src/main/java/org/mockito/session/MockitoSessionBuilder.java index b3a758b..474b7f9 100644 --- a/src/main/java/org/mockito/session/MockitoSessionBuilder.java +++ b/src/main/java/org/mockito/session/MockitoSessionBuilder.java @@ -47,7 +47,7 @@ public interface MockitoSessionBuilder { * like {@link org.mockito.Mock}. * <p> * In most scenarios, you only need to init mocks on a single test class instance. - * This method is useful for advanced framework integrations (like JUnit Jupiter), when a test uses multiple, e.g. nested, test class instances. + * This method is useful for advanced framework integrations (like JUnit5), when a test uses multiple, e.g. nested, test class instances. * <p> * This method calls {@link #initMocks(Object)} for each passed test class instance. * |