diff --git a/src/main/java/org/mockito/internal/configuration/InjectingAnnotationEngine.java b/src/main/java/org/mockito/internal/configuration/InjectingAnnotationEngine.java index ef9933d9d6..eeb019ade5 100644 --- a/src/main/java/org/mockito/internal/configuration/InjectingAnnotationEngine.java +++ b/src/main/java/org/mockito/internal/configuration/InjectingAnnotationEngine.java @@ -45,7 +45,7 @@ public class InjectingAnnotationEngine implements AnnotationEngine { public AutoCloseable process(Class clazz, Object testInstance) { List closeables = new ArrayList<>(); closeables.addAll(processIndependentAnnotations(testInstance.getClass(), testInstance)); - closeables.addAll(processInjectMocks(testInstance.getClass(), testInstance)); + closeables.add(injectCloseableMocks(testInstance)); return () -> { for (AutoCloseable closeable : closeables) { closeable.close(); @@ -53,17 +53,6 @@ public AutoCloseable process(Class clazz, Object testInstance) { }; } - private List processInjectMocks( - final Class clazz, final Object testInstance) { - List closeables = new ArrayList<>(); - Class classContext = clazz; - while (classContext != Object.class) { - closeables.add(injectCloseableMocks(testInstance)); - classContext = classContext.getSuperclass(); - } - return closeables; - } - private List processIndependentAnnotations( final Class clazz, final Object testInstance) { List closeables = new ArrayList<>(); diff --git a/src/test/java/org/mockito/internal/configuration/InjectingAnnotationEngineTest.java b/src/test/java/org/mockito/internal/configuration/InjectingAnnotationEngineTest.java deleted file mode 100644 index 274db3beca..0000000000 --- a/src/test/java/org/mockito/internal/configuration/InjectingAnnotationEngineTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2019 Mockito contributors - * This program is made available under the terms of the MIT License. - */ -package org.mockito.internal.configuration; - -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Spy; -import org.mockito.junit.MockitoJUnitRunner; - -class I {} - -@RunWith(MockitoJUnitRunner.class) -public class InjectingAnnotationEngineTest extends I { - @InjectMocks Target target; - @Mock Foo foo; - @Spy Bar bar = new Bar(); - - /* - If the test case has super classes, the @InjectMocks field has a field that not listed in the constructor argument - will fill by setter/property injection . - - https://github.com/mockito/mockito/issues/1631 - */ - @Test - public void injectMocks() { - Assert.assertEquals(foo, target.getFoo()); - Assert.assertNotNull(target.getBar()); - } - - public static class Target { - private final Foo foo; - private Bar bar; - - public Target(Foo foo) { - this.foo = foo; - } - - public Foo getFoo() { - return foo; - } - - public Bar getBar() { - return bar; - } - } - - public static class Foo {} - - public static class Bar {} -} diff --git a/subprojects/junit-jupiter/src/test/java/org/mockitousage/InjectMocksTest.java b/subprojects/junit-jupiter/src/test/java/org/mockitousage/InjectMocksTest.java new file mode 100644 index 0000000000..d153247819 --- /dev/null +++ b/subprojects/junit-jupiter/src/test/java/org/mockitousage/InjectMocksTest.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2018 Mockito contributors + * This program is made available under the terms of the MIT License. + */ +package org.mockitousage; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.assertj.core.api.Assertions.assertThat; + +class ToBeMockedInTestSuperClass{ + int identifier; + + public ToBeMockedInTestSuperClass(int identifier) { + this.identifier = identifier; + } +} + +class ToBeMocked{ + int identifier; + + public ToBeMocked(int identifier) { + this.identifier = identifier; + } +} + +class TestClassToBeInitiatedViaConstructorInSuperClass { + ToBeMockedInTestSuperClass toBeMockedInTestSuperClass; + + public TestClassToBeInitiatedViaConstructorInSuperClass(ToBeMockedInTestSuperClass toBeMockedInTestSuperClass) { + assert toBeMockedInTestSuperClass != null; + this.toBeMockedInTestSuperClass = new ToBeMockedInTestSuperClass(42); + } +} + +class TestClassToBeInitiatedViaConstructor{ + ToBeMockedInTestSuperClass toBeMockedInTestSuperClass; + ToBeMocked toBeMocked; + + public TestClassToBeInitiatedViaConstructor(ToBeMocked toBeMocked, ToBeMockedInTestSuperClass toBeMockedInTestSuperClass) { + assert toBeMocked != null; + assert toBeMockedInTestSuperClass != null; + this.toBeMocked = new ToBeMocked(42); + this.toBeMockedInTestSuperClass = new ToBeMockedInTestSuperClass(42); + } +} + +class SuperTestClass { + @Mock + ToBeMockedInTestSuperClass toBeMockedInTestSuperClass; + + @InjectMocks + TestClassToBeInitiatedViaConstructorInSuperClass testClassToBeInitiatedViaConstructorInSuperClass; + +} + +@ExtendWith(MockitoExtension.class) +class InjectMocksTest extends SuperTestClass { + + @Mock + ToBeMocked toBeMocked; + + @InjectMocks + TestClassToBeInitiatedViaConstructor testClassToBeInitiatedViaConstructor; + + /** + * Checks that {@link #testClassToBeInitiatedViaConstructor} holds instances that have identifier 42. + * It being 42 is proof that constructor injection was used over field injection. + */ + @Test + void given_instanceToBeInitializedByMockito_when_mocksRequestedByConstructorAreInTestAndSuperClass_should_useConstructorInjection() { + assertThat(testClassToBeInitiatedViaConstructor) + .extracting( + testInstance-> testInstance.toBeMocked.identifier, + testInstance-> testInstance.toBeMockedInTestSuperClass.identifier + ) + .containsExactly( + 42, + 42 + ); + } + + /** + * Checks that {@link #testClassToBeInitiatedViaConstructorInSuperClass} holds instances that have identifier 42. + * It being 42 is proof that constructor injection was used over field injection. + */ + @Test + public void given_instanceInSuperClassToBeInitializedByMockito_when_mocksRequestedAreInSuperClass_should_useConstructorInjection(){ + assertThat(testClassToBeInitiatedViaConstructorInSuperClass) + .extracting(yetAnotherClas1 -> yetAnotherClas1.toBeMockedInTestSuperClass.identifier) + .isEqualTo(42); + } + +}