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 14f52f3705..780742c64a 100644 --- a/src/main/java/org/mockito/internal/configuration/plugins/DefaultMockitoPlugins.java +++ b/src/main/java/org/mockito/internal/configuration/plugins/DefaultMockitoPlugins.java @@ -28,13 +28,14 @@ public class DefaultMockitoPlugins implements MockitoPlugins { static final String SUBCLASS_ALIAS = MockMakers.SUBCLASS; public static final Set MOCK_MAKER_ALIASES = new HashSet<>(); static final String MODULE_ALIAS = "member-accessor-module"; + static final String REFLECTION_ALIAS = "member-accessor-reflection"; static { // Keep the mapping: plugin interface name -> plugin implementation class name DEFAULT_PLUGINS.put(PluginSwitch.class.getName(), DefaultPluginSwitch.class.getName()); DEFAULT_PLUGINS.put( MockMaker.class.getName(), - "org.mockito.internal.creation.bytebuddy.ByteBuddyMockMaker"); + "org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker"); DEFAULT_PLUGINS.put( StackTraceCleanerProvider.class.getName(), "org.mockito.internal.exceptions.stacktrace.DefaultStackTraceCleanerProvider"); @@ -53,9 +54,11 @@ public class DefaultMockitoPlugins implements MockitoPlugins { MockitoLogger.class.getName(), "org.mockito.internal.util.ConsoleMockitoLogger"); DEFAULT_PLUGINS.put( MemberAccessor.class.getName(), - "org.mockito.internal.util.reflection.ReflectionMemberAccessor"); + "org.mockito.internal.util.reflection.ModuleMemberAccessor"); DEFAULT_PLUGINS.put( MODULE_ALIAS, "org.mockito.internal.util.reflection.ModuleMemberAccessor"); + DEFAULT_PLUGINS.put( + REFLECTION_ALIAS, "org.mockito.internal.util.reflection.ReflectionMemberAccessor"); DEFAULT_PLUGINS.put( DoNotMockEnforcer.class.getName(), "org.mockito.internal.configuration.DefaultDoNotMockEnforcer"); 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 ed12d2ffe2..009daa4ccb 100644 --- a/src/main/java/org/mockito/internal/creation/bytebuddy/InlineBytecodeGenerator.java +++ b/src/main/java/org/mockito/internal/creation/bytebuddy/InlineBytecodeGenerator.java @@ -205,6 +205,7 @@ public Class mockClass(MockFeatures features) { boolean subclassingRequired = !features.interfaces.isEmpty() || features.serializableMode != SerializableMode.NONE + || features.stripAnnotations || Modifier.isAbstract(features.mockedType.getModifiers()); checkSupportedCombination(subclassingRequired, features); @@ -416,6 +417,7 @@ public synchronized void clearAllCaches() { } mocked.clear(); flatMocked.clear(); + subclassEngine.clearAllCaches(); try { instrumentation.retransformClasses(types.toArray(new Class[0])); } catch (UnmodifiableClassException e) { diff --git a/src/main/java/org/mockito/internal/exceptions/stacktrace/DefaultStackTraceCleaner.java b/src/main/java/org/mockito/internal/exceptions/stacktrace/DefaultStackTraceCleaner.java index 6437ae4aa4..797515dea1 100644 --- a/src/main/java/org/mockito/internal/exceptions/stacktrace/DefaultStackTraceCleaner.java +++ b/src/main/java/org/mockito/internal/exceptions/stacktrace/DefaultStackTraceCleaner.java @@ -24,13 +24,20 @@ public boolean isIn(StackFrameMetadata e) { private boolean isIn(String className) { if (isFromMockitoRunner(className) || isFromMockitoRule(className)) { return true; - } else if (isMockDispatcher(className) || isFromMockito(className)) { + } else if (isMockDispatcher(className) + || isFromMockito(className) + || isMethodHandle(className)) { return false; } else { return true; } } + /* Some mock makers (like inline) use java.lang.invoke.MethodHandle to dispatch calls */ + private static boolean isMethodHandle(String className) { + return className.startsWith("java.lang.invoke.MethodHandle"); + } + private static boolean isMockDispatcher(String className) { return (className.contains("$$EnhancerByMockitoWithCGLIB$$") || className.contains("$MockitoMock$")); 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 a6e0b2c138..6f6476d046 100644 --- a/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsSmartNulls.java +++ b/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsSmartNulls.java @@ -8,9 +8,12 @@ import static org.mockito.internal.util.ObjectMethodsGuru.isToStringMethod; import java.io.Serializable; +import java.lang.reflect.Method; +import java.util.Arrays; import org.mockito.Mockito; import org.mockito.internal.creation.MockSettingsImpl; +import org.mockito.internal.creation.bytebuddy.MockAccess; import org.mockito.internal.debugging.LocationFactory; import org.mockito.internal.util.MockUtil; import org.mockito.invocation.InvocationOnMock; @@ -89,9 +92,28 @@ public Object answer(InvocationOnMock currentInvocation) throws Throwable { if (isToStringMethod(currentInvocation.getMethod())) { return "SmartNull returned by this unstubbed method call on a mock:\n" + unstubbedInvocation; + } else if (isMethodOf( + MockAccess.class, currentInvocation.getMock(), currentInvocation.getMethod())) { + /* The MockAccess methods should be called directly */ + return currentInvocation.callRealMethod(); } throw smartNullPointerException(unstubbedInvocation.toString(), location); } + + private static boolean isMethodOf(Class clazz, Object instance, Method method) { + if (!clazz.isInstance(instance)) { + return false; + } + + for (Method m : clazz.getDeclaredMethods()) { + if (m.getName().equalsIgnoreCase(method.getName()) + && Arrays.equals(m.getParameterTypes(), method.getParameterTypes())) { + return true; + } + } + + return false; + } } } diff --git a/src/main/java/org/mockito/internal/util/reflection/InstrumentationMemberAccessor.java b/src/main/java/org/mockito/internal/util/reflection/InstrumentationMemberAccessor.java index 13d8416586..61b3f06c46 100644 --- a/src/main/java/org/mockito/internal/util/reflection/InstrumentationMemberAccessor.java +++ b/src/main/java/org/mockito/internal/util/reflection/InstrumentationMemberAccessor.java @@ -188,7 +188,16 @@ public Object newInstance( onConstruction.invoke( () -> { try { - return DISPATCHER.invokeWithArguments(handle, arguments); + // Use handle.asFixedArity() to handle varargs bindings properly + // (as by default Java will create method handle with + // asVarargsCollector), fe: + // + // private static class Varargs { + // Varargs(String whatever, Observer... observers) { + // } + // } + return DISPATCHER.invokeWithArguments( + handle.asFixedArity(), arguments); } catch (Throwable throwable) { thrown.set(true); return throwable; @@ -372,17 +381,23 @@ private static void assureArguments( throw new IllegalArgumentException("Cannot access " + target + " on " + owner); } } - if (types.length != values.length) { + + Object[] args = values; + if (args == null) { + args = new Object[0]; + } + + if (types.length != args.length) { throw new IllegalArgumentException( "Incorrect number of arguments for " + target + ": expected " + types.length + " but recevied " - + values.length); + + args.length); } - for (int index = 0; index < values.length; index++) { - if (values[index] == null) { + for (int index = 0; index < args.length; index++) { + if (args[index] == null) { if (types[index].isPrimitive()) { throw new IllegalArgumentException( "Cannot assign null to primitive type " @@ -394,10 +409,10 @@ private static void assureArguments( } } else { Class resolved = WRAPPERS.getOrDefault(types[index], types[index]); - if (!resolved.isAssignableFrom(values[index].getClass())) { + if (!resolved.isAssignableFrom(args[index].getClass())) { throw new IllegalArgumentException( "Cannot assign value of type " - + values[index].getClass() + + args[index].getClass() + " to " + resolved + " for " diff --git a/src/test/java/org/mockito/MockitoTest.java b/src/test/java/org/mockito/MockitoTest.java index 168acb8f40..1ebbb89b80 100644 --- a/src/test/java/org/mockito/MockitoTest.java +++ b/src/test/java/org/mockito/MockitoTest.java @@ -7,16 +7,21 @@ import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.not; import static org.mockito.Mockito.times; import static org.mockito.internal.progress.ThreadSafeMockingProgress.mockingProgress; import java.util.List; +import org.junit.Assume; import org.junit.Test; import org.mockito.exceptions.base.MockitoException; import org.mockito.exceptions.misusing.NotAMockException; import org.mockito.exceptions.misusing.NullInsteadOfMockException; +import org.mockito.internal.configuration.plugins.Plugins; import org.mockito.internal.creation.MockSettingsImpl; +import org.mockito.plugins.InlineMockMaker; @SuppressWarnings("unchecked") public class MockitoTest { @@ -99,6 +104,8 @@ public void shouldValidateMockWhenCreatingInOrderObject() { @SuppressWarnings({"CheckReturnValue", "MockitoUsage"}) @Test public void shouldGiveExplanationOnStaticMockingWithoutInlineMockMaker() { + Assume.assumeThat(Plugins.getMockMaker(), not(instanceOf(InlineMockMaker.class))); + assertThatThrownBy( () -> { Mockito.mockStatic(Object.class); @@ -114,6 +121,8 @@ public void shouldGiveExplanationOnStaticMockingWithoutInlineMockMaker() { @SuppressWarnings({"CheckReturnValue", "MockitoUsage"}) @Test public void shouldGiveExplanationOnConstructionMockingWithoutInlineMockMaker() { + Assume.assumeThat(Plugins.getMockMaker(), not(instanceOf(InlineMockMaker.class))); + assertThatThrownBy( () -> { Mockito.mockConstruction(Object.class); @@ -126,6 +135,20 @@ public void shouldGiveExplanationOnConstructionMockingWithoutInlineMockMaker() { "Note that Mockito's inline mock maker is not supported on Android."); } + @SuppressWarnings({"CheckReturnValue", "MockitoUsage"}) + @Test + public void shouldGiveExplanationOnConstructionMockingWithInlineMockMaker() { + Assume.assumeThat(Plugins.getMockMaker(), instanceOf(InlineMockMaker.class)); + + assertThatThrownBy( + () -> { + Mockito.mockConstruction(Object.class); + }) + .isInstanceOf(MockitoException.class) + .hasMessageContainingAll( + "It is not possible to mock construction of the Object class to avoid inference with default object constructor chains"); + } + @Test public void shouldStartingMockSettingsContainDefaultBehavior() { // given diff --git a/src/test/java/org/mockito/internal/configuration/plugins/DefaultMockitoPluginsTest.java b/src/test/java/org/mockito/internal/configuration/plugins/DefaultMockitoPluginsTest.java index aa1835696e..61fc8e8ed1 100644 --- a/src/test/java/org/mockito/internal/configuration/plugins/DefaultMockitoPluginsTest.java +++ b/src/test/java/org/mockito/internal/configuration/plugins/DefaultMockitoPluginsTest.java @@ -10,7 +10,6 @@ import static org.mockito.internal.configuration.plugins.DefaultMockitoPlugins.SUBCLASS_ALIAS; import org.junit.Test; -import org.mockito.internal.creation.bytebuddy.ByteBuddyMockMaker; import org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker; import org.mockito.internal.util.ConsoleMockitoLogger; import org.mockito.plugins.InstantiatorProvider2; @@ -35,7 +34,8 @@ public void provides_plugins() throws Exception { "org.mockito.internal.creation.bytebuddy.ByteBuddyMockMaker", DefaultMockitoPlugins.getDefaultPluginClass(SUBCLASS_ALIAS)); assertEquals( - ByteBuddyMockMaker.class, plugins.getDefaultPlugin(MockMaker.class).getClass()); + InlineByteBuddyMockMaker.class, + plugins.getDefaultPlugin(MockMaker.class).getClass()); assertNotNull(plugins.getDefaultPlugin(InstantiatorProvider2.class)); assertEquals( ConsoleMockitoLogger.class, diff --git a/src/test/java/org/mockito/internal/runners/DefaultInternalRunnerTest.java b/src/test/java/org/mockito/internal/runners/DefaultInternalRunnerTest.java index c8912ec223..0e4e40076e 100644 --- a/src/test/java/org/mockito/internal/runners/DefaultInternalRunnerTest.java +++ b/src/test/java/org/mockito/internal/runners/DefaultInternalRunnerTest.java @@ -4,11 +4,14 @@ */ package org.mockito.internal.runners; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.not; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; +import org.junit.Assume; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; @@ -18,9 +21,11 @@ import org.junit.runner.notification.RunNotifier; import org.junit.runners.model.Statement; import org.mockito.Mock; +import org.mockito.internal.configuration.plugins.Plugins; import org.mockito.internal.junit.MockitoTestListener; import org.mockito.internal.junit.TestFinishedEvent; import org.mockito.internal.util.Supplier; +import org.mockito.plugins.InlineMockMaker; public class DefaultInternalRunnerTest { @@ -42,6 +47,9 @@ public void does_not_fail_when_tests_succeeds() throws Exception { @Test public void does_not_fail_second_test_when_first_test_fail() throws Exception { + // The TestFailOnInitialization is initialized properly by inline mock maker + Assume.assumeThat(Plugins.getMockMaker(), not(instanceOf(InlineMockMaker.class))); + new DefaultInternalRunner(TestFailOnInitialization.class, supplier) .run(newNotifier(runListener)); diff --git a/src/test/java/org/mockitousage/annotation/SpyAnnotationTest.java b/src/test/java/org/mockitousage/annotation/SpyAnnotationTest.java index 01edd3c687..daa71bed33 100644 --- a/src/test/java/org/mockitousage/annotation/SpyAnnotationTest.java +++ b/src/test/java/org/mockitousage/annotation/SpyAnnotationTest.java @@ -6,6 +6,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.not; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -22,6 +24,7 @@ import java.util.LinkedList; import java.util.List; +import org.junit.Assume; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -30,6 +33,8 @@ import org.mockito.MockitoAnnotations; import org.mockito.Spy; import org.mockito.exceptions.base.MockitoException; +import org.mockito.internal.configuration.plugins.Plugins; +import org.mockito.plugins.InlineMockMaker; import org.mockitoutil.TestBase; @SuppressWarnings("unused") @@ -188,8 +193,21 @@ class WithSpy { } } + @Test + public void should_spy_private_inner() throws Exception { + Assume.assumeThat(Plugins.getMockMaker(), instanceOf(InlineMockMaker.class)); + + WithInnerPrivate inner = new WithInnerPrivate(); + MockitoAnnotations.openMocks(inner); + + when(inner.spy_field.lenght()).thenReturn(10); + assertEquals(10, inner.spy_field.lenght()); + } + @Test public void should_report_private_inner_not_supported() throws Exception { + Assume.assumeThat(Plugins.getMockMaker(), not(instanceOf(InlineMockMaker.class))); + try { MockitoAnnotations.openMocks(new WithInnerPrivate()); fail(); @@ -287,7 +305,11 @@ private class InnerPrivateConcrete extends InnerPrivateAbstract {} static class WithInnerPrivate { @Spy private InnerPrivate spy_field; - private class InnerPrivate {} + private class InnerPrivate { + int lenght() { + return 0; + } + } private class InnerPrivateSub extends InnerPrivate {} } diff --git a/src/test/java/org/mockitousage/configuration/ClassCacheVersusClassReloadingTest.java b/src/test/java/org/mockitousage/configuration/ClassCacheVersusClassReloadingTest.java index 7d9c95061f..6c08198864 100644 --- a/src/test/java/org/mockitousage/configuration/ClassCacheVersusClassReloadingTest.java +++ b/src/test/java/org/mockitousage/configuration/ClassCacheVersusClassReloadingTest.java @@ -74,7 +74,9 @@ private static SimplePerRealmReloadingClassLoader.ReloadClassPredicate reloadMoc return new SimplePerRealmReloadingClassLoader.ReloadClassPredicate() { public boolean acceptReloadOf(String qualifiedName) { return (!qualifiedName.contains("net.bytebuddy") - && qualifiedName.contains("org.mockito")); + && qualifiedName.contains("org.mockito") + && !qualifiedName.contains( + "org.mockito.internal.creation.bytebuddy.inject")); } }; } diff --git a/src/test/java/org/mockitousage/misuse/InvalidUsageTest.java b/src/test/java/org/mockitousage/misuse/InvalidUsageTest.java index 35c135a62e..e4a8275be9 100644 --- a/src/test/java/org/mockitousage/misuse/InvalidUsageTest.java +++ b/src/test/java/org/mockitousage/misuse/InvalidUsageTest.java @@ -4,7 +4,10 @@ */ package org.mockitousage.misuse; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.not; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verifyNoInteractions; @@ -12,11 +15,14 @@ import static org.mockito.Mockito.when; import org.junit.After; +import org.junit.Assume; import org.junit.Test; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.exceptions.base.MockitoException; import org.mockito.exceptions.misusing.MissingMethodInvocationException; +import org.mockito.internal.configuration.plugins.Plugins; +import org.mockito.plugins.InlineMockMaker; import org.mockitousage.IMethods; import org.mockitoutil.TestBase; @@ -155,6 +161,8 @@ final class FinalClass {} @Test public void shouldNotAllowMockingFinalClassesIfDisabled() { + Assume.assumeThat(Plugins.getMockMaker(), not(instanceOf(InlineMockMaker.class))); + assertThatThrownBy( () -> { mock(FinalClass.class); @@ -166,6 +174,12 @@ public void shouldNotAllowMockingFinalClassesIfDisabled() { " - final class"); } + @Test + public void shouldAllowMockingFinalClassesIfEnabled() { + Assume.assumeThat(Plugins.getMockMaker(), instanceOf(InlineMockMaker.class)); + assertThat(mock(FinalClass.class)).isInstanceOf(FinalClass.class); + } + @SuppressWarnings({"CheckReturnValue", "MockitoUsage"}) @Test public void shouldNotAllowMockingPrimitives() { diff --git a/subprojects/android/src/main/resources/mockito-extensions/org.mockito.plugins.MemberAccessor b/subprojects/android/src/main/resources/mockito-extensions/org.mockito.plugins.MemberAccessor new file mode 100644 index 0000000000..71111e3378 --- /dev/null +++ b/subprojects/android/src/main/resources/mockito-extensions/org.mockito.plugins.MemberAccessor @@ -0,0 +1 @@ +member-accessor-reflection diff --git a/subprojects/module-test/src/test/java/org/mockito/moduletest/ModuleAccessTest.java b/subprojects/module-test/src/test/java/org/mockito/moduletest/ModuleAccessTest.java index 55923e77b5..460dc906f0 100644 --- a/subprojects/module-test/src/test/java/org/mockito/moduletest/ModuleAccessTest.java +++ b/subprojects/module-test/src/test/java/org/mockito/moduletest/ModuleAccessTest.java @@ -4,9 +4,11 @@ */ package org.mockito.moduletest; +import org.junit.Assume; import org.junit.Test; import org.mockito.Mockito; import org.mockito.exceptions.base.MockitoException; +import org.mockito.internal.configuration.plugins.Plugins; import org.mockito.internal.util.reflection.ModuleMemberAccessor; import org.mockito.internal.util.reflection.ReflectionMemberAccessor; @@ -17,6 +19,8 @@ import static junit.framework.TestCase.fail; import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.not; import static org.mockito.moduletest.ModuleUtil.layer; import static org.mockito.moduletest.ModuleUtil.modularJar; @@ -73,6 +77,8 @@ public void cannot_access_non_opened_module_with_reflection_member_accessor() th @Test public void cannot_read_unopened_private_field_but_exception_includes_cause() throws Exception { + Assume.assumeThat(Plugins.getMemberAccessor(), not(instanceOf(ModuleMemberAccessor.class))); + Path jar = modularJar(true, true, false, true); ModuleLayer layer = layer(jar, true, true); @@ -91,4 +97,21 @@ public void cannot_read_unopened_private_field_but_exception_includes_cause() th } } + @Test + public void can_read_unopened_private_field_but_exception_includes_cause() throws Exception { + Assume.assumeThat(Plugins.getMemberAccessor(), instanceOf(ModuleMemberAccessor.class)); + + Path jar = modularJar(true, true, false, true); + ModuleLayer layer = layer(jar, true, true); + + ClassLoader loader = layer.findLoader("mockito.test"); + Class type = loader.loadClass("sample.MyCallable"); + + @SuppressWarnings("unchecked") + Callable testInstance = (Callable) type.getDeclaredConstructor().newInstance(); + + Mockito.mockitoSession() + .initMocks(testInstance) + .startMocking(); + } } diff --git a/subprojects/module-test/src/test/java/org/mockito/moduletest/ReplicatingClassLoader.java b/subprojects/module-test/src/test/java/org/mockito/moduletest/ReplicatingClassLoader.java index c9cf0a32d2..144ff98767 100644 --- a/subprojects/module-test/src/test/java/org/mockito/moduletest/ReplicatingClassLoader.java +++ b/subprojects/module-test/src/test/java/org/mockito/moduletest/ReplicatingClassLoader.java @@ -53,4 +53,9 @@ public Class loadClass(String name) throws ClassNotFoundException { protected URL findResource(String moduleName, String name) { return Mockito.class.getResource("/" + name); } + + @Override + public InputStream getResourceAsStream(String name) { + return Mockito.class.getResourceAsStream("/" + name); + } } diff --git a/subprojects/programmatic-test/programmatic-test.gradle b/subprojects/programmatic-test/programmatic-test.gradle index 365dad93e3..39db6c6442 100644 --- a/subprojects/programmatic-test/programmatic-test.gradle +++ b/subprojects/programmatic-test/programmatic-test.gradle @@ -16,3 +16,7 @@ tasks.javadoc.enabled = false sourceCompatibility = 11 targetCompatibility = 11 + +test { + forkEvery = 1 +} diff --git a/src/test/java/org/mockitousage/annotation/ProgrammaticMockMakerAnnotationTest.java b/subprojects/programmatic-test/src/test/java/org/mockitousage/annotation/ProgrammaticMockMakerAnnotationTest.java similarity index 85% rename from src/test/java/org/mockitousage/annotation/ProgrammaticMockMakerAnnotationTest.java rename to subprojects/programmatic-test/src/test/java/org/mockitousage/annotation/ProgrammaticMockMakerAnnotationTest.java index ad5f2a50ae..2d495bed00 100644 --- a/src/test/java/org/mockitousage/annotation/ProgrammaticMockMakerAnnotationTest.java +++ b/subprojects/programmatic-test/src/test/java/org/mockitousage/annotation/ProgrammaticMockMakerAnnotationTest.java @@ -6,19 +6,25 @@ import static org.junit.Assert.assertEquals; +import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockMakers; import org.mockito.Mockito; -import org.mockitoutil.TestBase; +import org.mockito.MockitoAnnotations; -public class ProgrammaticMockMakerAnnotationTest extends TestBase { +public class ProgrammaticMockMakerAnnotationTest { @Mock(mockMaker = MockMakers.INLINE) ClassWithFinalMethod inlineMock; @Mock(mockMaker = MockMakers.SUBCLASS) ClassWithFinalMethod subclassMock; + @Before + public void init() { + MockitoAnnotations.openMocks(this); + } + @Test public void test_mock_uses_given_mock_maker() { Mockito.when(inlineMock.finalMethodCallingNonFinal()).thenReturn("MOCKED"); diff --git a/subprojects/proxy/src/main/resources/mockito-extensions/org.mockito.plugins.MemberAccessor b/subprojects/proxy/src/main/resources/mockito-extensions/org.mockito.plugins.MemberAccessor new file mode 100644 index 0000000000..71111e3378 --- /dev/null +++ b/subprojects/proxy/src/main/resources/mockito-extensions/org.mockito.plugins.MemberAccessor @@ -0,0 +1 @@ +member-accessor-reflection