diff --git a/src/main/java/org/mockito/Mock.java b/src/main/java/org/mockito/Mock.java index 7c3e036083..5be0ae3439 100644 --- a/src/main/java/org/mockito/Mock.java +++ b/src/main/java/org/mockito/Mock.java @@ -13,7 +13,6 @@ import java.lang.annotation.Target; import org.mockito.junit.MockitoJUnitRunner; -import org.mockito.quality.Strictness; import org.mockito.stubbing.Answer; /** @@ -34,12 +33,13 @@ * @Mock(name = "database") private ArticleDatabase dbMock; * @Mock(answer = RETURNS_MOCKS) private UserProvider userProvider; * @Mock(extraInterfaces = {Queue.class, Observer.class}) private ArticleMonitor articleMonitor; + * @Mock(strictness = Mock.Strictness.LENIENT) private ArticleConsumer articleConsumer; * @Mock(stubOnly = true) private Logger logger; * * private ArticleManager manager; * * @Before public void setup() { - * manager = new ArticleManager(userProvider, database, calculator, articleMonitor, logger); + * manager = new ArticleManager(userProvider, database, calculator, articleMonitor, articleConsumer, logger); * } * } * @@ -117,10 +117,43 @@ boolean lenient() default false; /** - * Mock will have custom strictness, see {@link MockSettings#strictness(Strictness)}. + * Mock will have custom strictness, see {@link MockSettings#strictness(org.mockito.quality.Strictness)}. * For examples how to use 'Mock' annotation and parameters see {@link Mock}. * * @since 4.6.0 */ - Strictness strictness() default Strictness.STRICT_STUBS; + Strictness strictness() default Strictness.NOT_SET; + + enum Strictness { + + /** + * Default value used to indicate the mock does not override the inherited strictness. + */ + NOT_SET(null), + + /** + * see {@link org.mockito.quality.Strictness#LENIENT} + */ + LENIENT(org.mockito.quality.Strictness.LENIENT), + + /** + * see {@link org.mockito.quality.Strictness#WARN} + */ + WARN(org.mockito.quality.Strictness.WARN), + + /** + * see {@link org.mockito.quality.Strictness#STRICT_STUBS} + */ + STRICT_STUBS(org.mockito.quality.Strictness.STRICT_STUBS); + + private final org.mockito.quality.Strictness outer; + + Strictness(org.mockito.quality.Strictness outer) { + this.outer = outer; + } + + public org.mockito.quality.Strictness outer() { + return outer; + } + } } diff --git a/src/main/java/org/mockito/internal/configuration/MockAnnotationProcessor.java b/src/main/java/org/mockito/internal/configuration/MockAnnotationProcessor.java index 484c9102e4..7250f05db6 100644 --- a/src/main/java/org/mockito/internal/configuration/MockAnnotationProcessor.java +++ b/src/main/java/org/mockito/internal/configuration/MockAnnotationProcessor.java @@ -45,10 +45,12 @@ public static Object processAnnotationForMock( if (annotation.stubOnly()) { mockSettings.stubOnly(); } - mockSettings.strictness(annotation.strictness()); if (annotation.lenient()) { mockSettings.lenient(); } + if (annotation.strictness() != Mock.Strictness.NOT_SET) { + mockSettings.strictness(annotation.strictness().outer()); + } // see @Mock answer default value mockSettings.defaultAnswer(annotation.answer()); diff --git a/src/main/java/org/mockito/internal/creation/MockSettingsImpl.java b/src/main/java/org/mockito/internal/creation/MockSettingsImpl.java index e1dcd48f9e..f73a718298 100644 --- a/src/main/java/org/mockito/internal/creation/MockSettingsImpl.java +++ b/src/main/java/org/mockito/internal/creation/MockSettingsImpl.java @@ -247,10 +247,10 @@ public MockSettings lenient() { @Override public MockSettings strictness(Strictness strictness) { - this.strictness = strictness; if (strictness == null) { throw strictnessDoesNotAcceptNullParameter(); } + this.strictness = strictness; return this; } 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 50bb937696..13939f6fbd 100644 --- a/src/main/java/org/mockito/internal/creation/settings/CreationSettings.java +++ b/src/main/java/org/mockito/internal/creation/settings/CreationSettings.java @@ -45,7 +45,7 @@ public class CreationSettings implements MockCreationSettings, Serializabl private boolean useConstructor; private Object outerClassInstance; private Object[] constructorArgs; - protected Strictness strictness = Strictness.STRICT_STUBS; + protected Strictness strictness = null; public CreationSettings() {} diff --git a/src/test/java/org/mockito/MockTest.java b/src/test/java/org/mockito/MockTest.java new file mode 100644 index 0000000000..75272c8cab --- /dev/null +++ b/src/test/java/org/mockito/MockTest.java @@ -0,0 +1,28 @@ +package org.mockito; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(value = Parameterized.class) +public class MockTest { + + public org.mockito.quality.Strictness strictness; + + public MockTest(org.mockito.quality.Strictness strictness) { + this.strictness = strictness; + } + + @Test + public void shouldHaveMatchingEnumInMockStrictnessEnum() { + final Mock.Strictness mockStrictness = Mock.Strictness.valueOf(this.strictness.name()); + assertThat(mockStrictness.outer()).isEqualTo(strictness); + } + + @Parameterized.Parameters + public static org.mockito.quality.Strictness[] data() { + return org.mockito.quality.Strictness.values(); + } +} diff --git a/src/test/java/org/mockitousage/strictness/StrictnessMockAnnotationTest.java b/src/test/java/org/mockitousage/strictness/StrictnessMockAnnotationTest.java index c035b3d708..364a07b709 100644 --- a/src/test/java/org/mockitousage/strictness/StrictnessMockAnnotationTest.java +++ b/src/test/java/org/mockitousage/strictness/StrictnessMockAnnotationTest.java @@ -20,7 +20,7 @@ public class StrictnessMockAnnotationTest { public @Rule MockitoRule rule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS); - @Mock(strictness = Strictness.LENIENT) + @Mock(strictness = Mock.Strictness.LENIENT) IMethods lenientMock; @Mock IMethods regularMock; diff --git a/subprojects/junit-jupiter/src/test/java/org/mockitousage/ProductionCode.java b/subprojects/junit-jupiter/src/test/java/org/mockitousage/ProductionCode.java new file mode 100644 index 0000000000..7c1147501c --- /dev/null +++ b/subprojects/junit-jupiter/src/test/java/org/mockitousage/ProductionCode.java @@ -0,0 +1,11 @@ +package org.mockitousage; + +import java.util.function.Predicate; + +public class ProductionCode { + + @SuppressWarnings("ReturnValueIgnored") + public static void simpleMethod(Predicate mock, String argument) { + mock.test(argument); + } +} diff --git a/subprojects/junit-jupiter/src/test/java/org/mockitousage/StrictnessTest.java b/subprojects/junit-jupiter/src/test/java/org/mockitousage/StrictnessTest.java index 31a5d6a649..1b63d66cc4 100644 --- a/subprojects/junit-jupiter/src/test/java/org/mockitousage/StrictnessTest.java +++ b/subprojects/junit-jupiter/src/test/java/org/mockitousage/StrictnessTest.java @@ -21,7 +21,9 @@ import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; +import java.util.Optional; import java.util.function.Function; +import java.util.function.Predicate; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass; @@ -162,6 +164,29 @@ void inherits_strictness_from_base_class() { assertThat(result.getStatus()).isEqualTo(TestExecutionResult.Status.SUCCESSFUL); } + @ExtendWith(MockitoExtension.class) + @MockitoSettings(strictness = Strictness.LENIENT) + static class LenientMockitoSettings { + + @Mock + private Predicate rootMock; + + @Test + void should_not_throw_on_potential_stubbing_issue() { + Mockito.doReturn(true).when(rootMock).test("Foo"); + + ProductionCode.simpleMethod(rootMock, "Bar"); + } + } + + @Test + void use_strictness_from_settings_annotation() { + TestExecutionResult result = invokeTestClassAndRetrieveMethodResult(LenientMockitoSettings.class); + + assertThat(result.getThrowable()).isEqualTo(Optional.empty()); + assertThat(result.getStatus()).isEqualTo(TestExecutionResult.Status.SUCCESSFUL); + } + private TestExecutionResult invokeTestClassAndRetrieveMethodResult(Class clazz) { LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request() .selectors(