From acddbbc00d1754d3c4da893f6322d03d782fb1a8 Mon Sep 17 00:00:00 2001 From: Stephan Schroevers Date: Sat, 14 Jan 2023 23:17:48 +0100 Subject: [PATCH 01/12] Annotate `Mockito#{mock,spy}(T... reified)` with `@SafeVarargs` (#2866) This avoids "Unchecked generics array creation for varargs parameter" warnings at the call site. --- src/main/java/org/mockito/Mockito.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/mockito/Mockito.java b/src/main/java/org/mockito/Mockito.java index 31eed046cf..ff543e74b5 100644 --- a/src/main/java/org/mockito/Mockito.java +++ b/src/main/java/org/mockito/Mockito.java @@ -1932,6 +1932,7 @@ public class Mockito extends ArgumentMatchers { * @return mock object * @since 4.9.0 */ + @SafeVarargs public static T mock(T... reified) { if (reified.length > 0) { throw new IllegalArgumentException( @@ -2161,6 +2162,7 @@ public static T spy(Class classToSpy) { * @return spy object * @since 4.9.0 */ + @SafeVarargs public static T spy(T... reified) { if (reified.length > 0) { throw new IllegalArgumentException( From 0aba0d5b031b4282c9b6686add2b443bda761817 Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Sat, 14 Jan 2023 23:46:48 +0100 Subject: [PATCH 02/12] Update current version in README (#2867) --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f1f4b11530..d523402135 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,11 @@ Most popular mocking framework for Java [![Javadoc](https://www.javadoc.io/badge/org.mockito/mockito-core.svg)](https://www.javadoc.io/doc/org.mockito/mockito-core) -## Current version is 4.x -Still on Mockito 1.x? See [what's new](https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2) in Mockito 2! [Mockito 3](https://github.com/mockito/mockito/releases/tag/v3.0.0) does not introduce any breaking API changes, but now requires Java 8 over Java 6 for Mockito 2. +## Current version is 5.x +Still on Mockito 1.x? See [what's new](https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2) in Mockito 2! +[Mockito 3](https://github.com/mockito/mockito/releases/tag/v3.0.0) does not introduce any breaking API changes, but now requires Java 8 over Java 6 for Mockito 2. [Mockito 4](https://github.com/mockito/mockito/releases/tag/v4.0.0) removes deprecated API. +[Mockito 5](https://github.com/mockito/mockito/releases/tag/v5.0.0) switches the default mockmaker to mockito-inline, and now requires Java 11. ## Mockito for enterprise From 484de454af8a12da8e2944ab889a262caac73ae0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B3bert=20Papp?= Date: Sun, 15 Jan 2023 12:59:27 +0000 Subject: [PATCH 03/12] Update release badge to 5.x (#2869) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d523402135..0a34afc47b 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Most popular mocking framework for Java [![Coverage Status](https://img.shields.io/codecov/c/github/mockito/mockito.svg)](https://codecov.io/github/mockito/mockito) [![MIT License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/mockito/mockito/blob/main/LICENSE) -[![Release Notes](https://img.shields.io/badge/release%20notes-3.x-yellow.svg)](https://github.com/mockito/mockito/releases/) +[![Release Notes](https://img.shields.io/badge/release%20notes-5.x-yellow.svg)](https://github.com/mockito/mockito/releases/) [![Maven Central](https://img.shields.io/maven-central/v/org.mockito/mockito-core.svg)](https://search.maven.org/artifact/org.mockito/mockito-core/) [![Javadoc](https://www.javadoc.io/badge/org.mockito/mockito-core.svg)](https://www.javadoc.io/doc/org.mockito/mockito-core) From f2a47c35b8b16a8b1c560b9d93bc3cce62a3e310 Mon Sep 17 00:00:00 2001 From: Ashley <73482956+ascopes@users.noreply.github.com> Date: Sun, 15 Jan 2023 17:25:39 +0000 Subject: [PATCH 04/12] Improve examples for InOrder (#2843) Include some context in InOrder examples and add an example that uses a static mock as well. --- src/main/java/org/mockito/InOrder.java | 30 +++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/mockito/InOrder.java b/src/main/java/org/mockito/InOrder.java index 3cb047a4c4..ee71ae197c 100644 --- a/src/main/java/org/mockito/InOrder.java +++ b/src/main/java/org/mockito/InOrder.java @@ -12,13 +12,41 @@ * Allows verification in order. E.g: * *

+ * // Given
+ * First firstMock = mock(First.class);
+ * Second secondMock = mock(Second.class);
  * InOrder inOrder = inOrder(firstMock, secondMock);
  *
+ * // When
+ * firstMock.add("was called first");
+ * secondMock.add("was called second");
+ *
+ * // Then
  * inOrder.verify(firstMock).add("was called first");
  * inOrder.verify(secondMock).add("was called second");
+ * inOrder.verifyNoMoreInteractions();
+ * 
+ * + * Static mocks can be verified alongside non-static mocks. E.g: + * + *

+ * // Given
+ * First firstMock = mock(First.class);
+ * MockedStatic staticSecondMock = mockStatic(StaticSecond.class);
+ * InOrder inOrder = inOrder(firstMock, StaticSecond.class);
+ *
+ * // When
+ * firstMock.add("was called first");
+ * StaticSecond.doSomething("foobar");
+ *
+ * // Then
+ * inOrder.verify(firstMock).add("was called first");
+ * inOrder.verify(staticSecondMock, () -> StaticSecond.doSomething("foobar"));
+ * inOrder.verifyNoMoreInteractions();
  * 
* - * As of Mockito 1.8.4 you can verifyNoMoreInteractions() in order-sensitive way. Read more: {@link InOrder#verifyNoMoreInteractions()} + * As of Mockito 1.8.4 you can verifyNoMoreInteractions() in order-sensitive way. Read more: + * {@link InOrder#verifyNoMoreInteractions()}. *

* * See examples in javadoc for {@link Mockito} class From 23e344ec7b7c11743331ace30f26c21da12767ba Mon Sep 17 00:00:00 2001 From: Stephan Schroevers Date: Sun, 15 Jan 2023 18:31:27 +0100 Subject: [PATCH 05/12] Remove broken link from `CONTRIBUTING.md` (#2870) Fixes #2868 --- .github/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 8609981c54..5a49c782b4 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -54,7 +54,7 @@ Things we pay attention in a PR : * In the code, always test your feature / change, in unit tests and in our `acceptance test suite` located in `org.mockitousage`. Older tests will be migrated when a test is modified. * New test methods should follow a snake case convention (`ensure_that_stuff_is_doing_that`), this allows the test name to be fully expressive on intent while still readable. * When reporting errors to the users, if it's a user report report it gently and explain how a user should deal with it, see the `Reporter` class. However not all errors should go there, some unlikely technical errors don't need to be in the `Reporter` class. -* Documentation !!! Always document with love the public API. Internals could use some love too. In all cases the code should _auto-document_ itself like any [well designed API](rebased and squashed if necessary, so that each commit clearly changes one things and there are no extraneous fix-ups). +* Documentation !!! Always document with love the public API. Internals could use some love too. In all cases the code should _auto-document_ itself like any well-designed API. * We use (4) spaces instead of tabs. Make sure line ending is Unix style (LF). More on line ending on the [Github help](https://help.github.com/articles/dealing-with-line-endings/). From f4d7c346b1783c4a14aa8905ec96aa16f9f2fdd5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Jan 2023 19:32:17 +0100 Subject: [PATCH 06/12] Bump com.diffplug.spotless from 6.12.1 to 6.13.0 (#2871) Bumps com.diffplug.spotless from 6.12.1 to 6.13.0. --- updated-dependencies: - dependency-name: com.diffplug.spotless dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 9698007a75..f05c97fa31 100644 --- a/build.gradle +++ b/build.gradle @@ -20,7 +20,7 @@ buildscript { } plugins { - id 'com.diffplug.spotless' version '6.12.1' + id 'com.diffplug.spotless' version '6.13.0' id 'eclipse' id 'com.github.ben-manes.versions' version '0.44.0' id 'biz.aQute.bnd.builder' version '6.4.0' From 1418769a9f89060f7035a48094d0bb2eba1e0ec5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Jan 2023 23:23:20 +0100 Subject: [PATCH 07/12] Bump assertj-core from 3.24.1 to 3.24.2 (#2875) Bumps assertj-core from 3.24.1 to 3.24.2. --- updated-dependencies: - dependency-name: org.assertj:assertj-core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/dependencies.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index ce6c0fdbdd..45f0353e9b 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -13,7 +13,7 @@ libraries.junitJupiterApi = "org.junit.jupiter:junit-jupiter-api:${versions.juni libraries.junitPlatformLauncher = 'org.junit.platform:junit-platform-launcher:1.9.2' libraries.junitJupiterEngine = "org.junit.jupiter:junit-jupiter-engine:${versions.junitJupiter}" libraries.junitVintageEngine = "org.junit.vintage:junit-vintage-engine:${versions.junitJupiter}" -libraries.assertj = 'org.assertj:assertj-core:3.24.1' +libraries.assertj = 'org.assertj:assertj-core:3.24.2' libraries.hamcrest = 'org.hamcrest:hamcrest-core:2.2' libraries.opentest4j = 'org.opentest4j:opentest4j:1.2.0' From 96452fa7fb1a297323dfd998953489deeca64e28 Mon Sep 17 00:00:00 2001 From: Andriy Redko Date: Thu, 19 Jan 2023 03:41:28 -0500 Subject: [PATCH 08/12] Make sure the tests use mock maker with intended member accessor (#2872) Fixes #2855 Signed-off-by: Andriy Redko --- .github/workflows/ci.yml | 18 ++++-- gradle/mockito-core/testing.gradle | 43 ++++++++++---- .../plugins/DefaultMockitoPlugins.java | 4 ++ .../configuration/plugins/PluginRegistry.java | 4 +- .../junit/DefaultStubbingLookupListener.java | 15 +++-- src/test/java/org/mockito/MockitoEnvTest.java | 59 +++++++++++++++++++ .../spies/PartialMockingWithSpiesTest.java | 33 +++++++++++ .../plugins/switcher/MyPluginSwitch.java | 4 ++ 8 files changed, 153 insertions(+), 27 deletions(-) create mode 100644 src/test/java/org/mockito/MockitoEnvTest.java diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 58cb41b62c..0c57e59086 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,7 +30,12 @@ jobs: strategy: matrix: java: [11, 17] - mock-maker: ['mock-maker-default', 'mock-maker-inline', 'mock-maker-subclass'] + entry: + - { mock-maker: 'mock-maker-default', member-accessor: 'member-accessor-default' } + - { mock-maker: 'mock-maker-inline', member-accessor: 'member-accessor-module' } + - { mock-maker: 'mock-maker-subclass', member-accessor: 'member-accessor-module' } + - { mock-maker: 'mock-maker-subclass', member-accessor: 'member-accessor-reflection' } + - { mock-maker: 'mock-maker-inline', member-accessor: 'member-accessor-reflection' } # All build steps # SINGLE-MATRIX-JOB means that the step does not need to be executed on every job in the matrix @@ -48,21 +53,22 @@ jobs: java-version: ${{ matrix.java }} - name: 3. Validate Gradle wrapper - if: matrix.java == 11 && matrix.mock-maker == 'mock-maker-default' # SINGLE-MATRIX-JOB + if: matrix.java == 11 && matrix.entry.mock-maker == 'mock-maker-default' # SINGLE-MATRIX-JOB uses: gradle/wrapper-validation-action@v1.0.5 # https://github.com/gradle/wrapper-validation-action - name: 4. Build and check reproducibility of artifacts (single job only) - if: matrix.java == 11 && matrix.mock-maker == 'mock-maker-default' # SINGLE-MATRIX-JOB + if: matrix.java == 11 && matrix.entry.mock-maker == 'mock-maker-default' # SINGLE-MATRIX-JOB run: ./check_reproducibility.sh - name: 5. Spotless check (single job only). Run './gradlew spotlessApply' locally if this job fails. - if: matrix.java == 11 && matrix.mock-maker == 'mock-maker-default' # SINGLE-MATRIX-JOB + if: matrix.java == 11 && matrix.entry.mock-maker == 'mock-maker-default' # SINGLE-MATRIX-JOB run: ./gradlew spotlessCheck - - name: 6. Build on Java ${{ matrix.java }} with ${{ matrix.mock-maker }} + - name: 6. Build on Java ${{ matrix.java }} with ${{ matrix.entry.mock-maker }} and ${{ matrix.entry.member-accessor }} run: ./gradlew build idea --scan env: - MOCK_MAKER: ${{ matrix.mock-maker }} + MOCK_MAKER: ${{ matrix.entry.mock-maker }} + MEMBER_ACCESSOR: ${{ matrix.entry.member-accessor }} - name: 7. Upload coverage report run: | diff --git a/gradle/mockito-core/testing.gradle b/gradle/mockito-core/testing.gradle index a7c14c1f62..79e2996b6c 100644 --- a/gradle/mockito-core/testing.gradle +++ b/gradle/mockito-core/testing.gradle @@ -6,24 +6,43 @@ if (java11 != null) { } } -task(createTestResources).doLast { - def mockMakerFile = new File("$projectDir/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker") - if (System.env.MOCK_MAKER != null) { - logger.info("Using MockMaker ${System.env.MOCK_MAKER}") - mockMakerFile.parentFile.mkdirs() - mockMakerFile.createNewFile() - mockMakerFile.write(System.env.MOCK_MAKER) - } else { - logger.info("Using default MockMaker") +task(createTestResources) { + doLast { + // Configure MockMaker from environment (if specified), otherwise use default + def mockMakerFile = new File("$sourceSets.test.output.resourcesDir/mockito-extensions/org.mockito.plugins.MockMaker") + if (System.env.MOCK_MAKER != null && !System.env.MOCK_MAKER.endsWith("default")) { + logger.info("Using MockMaker ${System.env.MOCK_MAKER}") + mockMakerFile.parentFile.mkdirs() + mockMakerFile.createNewFile() + mockMakerFile.write(System.env.MOCK_MAKER) + } else { + logger.info("Using default MockMaker") + } + + // Configure MemberAccessor from environment (if specified), otherwise use default + def memberAccessorFile = new File("$sourceSets.test.output.resourcesDir/mockito-extensions/org.mockito.plugins.MemberAccessor") + if (System.env.MEMBER_ACCESSOR != null && !System.env.MEMBER_ACCESSOR.endsWith("default")) { + logger.info("Using MemberAccessor ${System.env.MEMBER_ACCESSOR}") + memberAccessorFile.parentFile.mkdirs() + memberAccessorFile.createNewFile() + memberAccessorFile.write(System.env.MEMBER_ACCESSOR) + } else { + logger.info("Using default MemberAccessor") + } } } task(removeTestResources).doLast { - def mockMakerFile = new File("$projectDir/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker") + def mockMakerFile = new File("$sourceSets.test.output.resourcesDir/mockito-extensions/org.mockito.plugins.MockMaker") if (mockMakerFile.exists()) { mockMakerFile.delete() } + + def memberAccessorFile = new File("$sourceSets.test.output.resourcesDir/mockito-extensions/org.mockito.plugins.MemberAccessor") + if (memberAccessorFile.exists()) { + memberAccessorFile.delete() + } } -compileTestJava.dependsOn createTestResources -compileTestJava.finalizedBy removeTestResources +processTestResources.finalizedBy(createTestResources) +test.finalizedBy(removeTestResources) 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 780742c64a..365c350e93 100644 --- a/src/main/java/org/mockito/internal/configuration/plugins/DefaultMockitoPlugins.java +++ b/src/main/java/org/mockito/internal/configuration/plugins/DefaultMockitoPlugins.java @@ -29,6 +29,7 @@ public class DefaultMockitoPlugins implements MockitoPlugins { 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"; + public static final Set MEMBER_ACCESSOR_ALIASES = new HashSet<>(); static { // Keep the mapping: plugin interface name -> plugin implementation class name @@ -66,6 +67,9 @@ public class DefaultMockitoPlugins implements MockitoPlugins { MOCK_MAKER_ALIASES.add(INLINE_ALIAS); MOCK_MAKER_ALIASES.add(PROXY_ALIAS); MOCK_MAKER_ALIASES.add(SUBCLASS_ALIAS); + + MEMBER_ACCESSOR_ALIASES.add(MODULE_ALIAS); + MEMBER_ACCESSOR_ALIASES.add(REFLECTION_ALIAS); } @Override diff --git a/src/main/java/org/mockito/internal/configuration/plugins/PluginRegistry.java b/src/main/java/org/mockito/internal/configuration/plugins/PluginRegistry.java index 6abaedbaef..72f5d8e7d5 100644 --- a/src/main/java/org/mockito/internal/configuration/plugins/PluginRegistry.java +++ b/src/main/java/org/mockito/internal/configuration/plugins/PluginRegistry.java @@ -27,7 +27,9 @@ class PluginRegistry { .loadPlugin(MockMaker.class); private final MemberAccessor memberAccessor = - new PluginLoader(pluginSwitch, DefaultMockitoPlugins.MODULE_ALIAS) + new PluginLoader( + pluginSwitch, + DefaultMockitoPlugins.MEMBER_ACCESSOR_ALIASES.toArray(new String[0])) .loadPlugin(MemberAccessor.class); private final StackTraceCleanerProvider stackTraceCleanerProvider = diff --git a/src/main/java/org/mockito/internal/junit/DefaultStubbingLookupListener.java b/src/main/java/org/mockito/internal/junit/DefaultStubbingLookupListener.java index c71386346e..48ba775100 100644 --- a/src/main/java/org/mockito/internal/junit/DefaultStubbingLookupListener.java +++ b/src/main/java/org/mockito/internal/junit/DefaultStubbingLookupListener.java @@ -10,6 +10,7 @@ import java.util.Collection; import java.util.LinkedList; import java.util.List; +import java.util.Objects; import org.mockito.internal.exceptions.Reporter; import org.mockito.internal.stubbing.UnusedStubbingReporting; @@ -68,17 +69,15 @@ private static List potentialArgMismatches( List matchingStubbings = new LinkedList<>(); for (Stubbing s : stubbings) { if (UnusedStubbingReporting.shouldBeReported(s) - && s.getInvocation() - .getMethod() - .getName() - .equals(invocation.getMethod().getName()) + && Objects.equals( + s.getInvocation().getMethod().getName(), + invocation.getMethod().getName()) // If stubbing and invocation are in the same source file we assume they are in // the test code, // and we don't flag it as mismatch: - && !s.getInvocation() - .getLocation() - .getSourceFile() - .equals(invocation.getLocation().getSourceFile())) { + && !Objects.equals( + s.getInvocation().getLocation().getSourceFile(), + invocation.getLocation().getSourceFile())) { matchingStubbings.add(s.getInvocation()); } } diff --git a/src/test/java/org/mockito/MockitoEnvTest.java b/src/test/java/org/mockito/MockitoEnvTest.java new file mode 100644 index 0000000000..1a162e9390 --- /dev/null +++ b/src/test/java/org/mockito/MockitoEnvTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021 Mockito contributors + * This program is made available under the terms of the MIT License. + */ +package org.mockito; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.CoreMatchers.endsWith; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.nullValue; + +import org.junit.Assume; +import org.junit.Test; +import org.mockito.internal.configuration.plugins.DefaultMockitoPlugins; +import org.mockito.internal.configuration.plugins.Plugins; +import org.mockito.plugins.MemberAccessor; +import org.mockito.plugins.MockMaker; + +public class MockitoEnvTest { + @Test + public void uses_default_mock_maker_from_env() { + final String mockMaker = System.getenv("MOCK_MAKER"); + Assume.assumeThat(mockMaker, not(nullValue())); + Assume.assumeThat(mockMaker, endsWith("default")); + + assertThat(DefaultMockitoPlugins.getDefaultPluginClass(MockMaker.class.getName())) + .isEqualTo(Plugins.getMockMaker().getClass().getName()); + } + + @Test + public void uses_mock_maker_from_env() { + final String mockMaker = System.getenv("MOCK_MAKER"); + Assume.assumeThat(mockMaker, not(nullValue())); + Assume.assumeThat(mockMaker, not(endsWith("default"))); + + assertThat(DefaultMockitoPlugins.getDefaultPluginClass(mockMaker)) + .isEqualTo(Plugins.getMockMaker().getClass().getName()); + } + + @Test + public void uses_default_member_accessor_from_env() { + final String memberAccessor = System.getenv("MEMBER_ACCESSOR"); + Assume.assumeThat(memberAccessor, not(nullValue())); + Assume.assumeThat(memberAccessor, endsWith("default")); + + assertThat(DefaultMockitoPlugins.getDefaultPluginClass(MemberAccessor.class.getName())) + .isEqualTo(Plugins.getMemberAccessor().getClass().getName()); + } + + @Test + public void uses_member_accessor_from_env() { + final String memberAccessor = System.getenv("MEMBER_ACCESSOR"); + Assume.assumeThat(memberAccessor, not(nullValue())); + Assume.assumeThat(memberAccessor, not(endsWith("default"))); + + assertThat(DefaultMockitoPlugins.getDefaultPluginClass(memberAccessor)) + .isEqualTo(Plugins.getMemberAccessor().getClass().getName()); + } +} diff --git a/src/test/java/org/mockitousage/spies/PartialMockingWithSpiesTest.java b/src/test/java/org/mockitousage/spies/PartialMockingWithSpiesTest.java index bf616f8d9f..4efcb2b275 100644 --- a/src/test/java/org/mockitousage/spies/PartialMockingWithSpiesTest.java +++ b/src/test/java/org/mockitousage/spies/PartialMockingWithSpiesTest.java @@ -4,6 +4,8 @@ */ package org.mockitousage.spies; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.not; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import static org.mockito.Mockito.doThrow; @@ -13,8 +15,12 @@ import static org.mockitoutil.Conditions.methodsInStackTrace; import org.assertj.core.api.Assertions; +import org.junit.Assume; import org.junit.Before; import org.junit.Test; +import org.mockito.internal.configuration.plugins.Plugins; +import org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker; +import org.mockito.internal.util.reflection.ReflectionMemberAccessor; import org.mockitoutil.TestBase; @SuppressWarnings("unchecked") @@ -104,6 +110,9 @@ public void shouldAllowStubbingWithThrowablesMethodsThatDelegateToOtherMethods() @Test public void shouldStackTraceGetFilteredOnUserExceptions() { + Assume.assumeThat( + Plugins.getMemberAccessor(), not(instanceOf(ReflectionMemberAccessor.class))); + try { // when spy.getNameButDelegateToMethodThatThrows(); @@ -119,6 +128,30 @@ public void shouldStackTraceGetFilteredOnUserExceptions() { } } + @Test + public void shouldStackTraceGetFilteredOnUserExceptionsReflection() { + Assume.assumeThat(Plugins.getMockMaker(), instanceOf(InlineByteBuddyMockMaker.class)); + Assume.assumeThat(Plugins.getMemberAccessor(), instanceOf(ReflectionMemberAccessor.class)); + + try { + // when + spy.getNameButDelegateToMethodThatThrows(); + fail(); + } catch (Throwable t) { + // then + Assertions.assertThat(t) + .has( + methodsInStackTrace( + "throwSomeException", + "invoke0", + "invoke", + "invoke", + "invoke", + "getNameButDelegateToMethodThatThrows", + "shouldStackTraceGetFilteredOnUserExceptionsReflection")); + } + } + // @Test //manual verification public void verifyTheStackTrace() { spy.getNameButDelegateToMethodThatThrows(); diff --git a/subprojects/extTest/src/test/java/org/mockitousage/plugins/switcher/MyPluginSwitch.java b/subprojects/extTest/src/test/java/org/mockitousage/plugins/switcher/MyPluginSwitch.java index eb4423f361..cf60ee63ec 100644 --- a/subprojects/extTest/src/test/java/org/mockitousage/plugins/switcher/MyPluginSwitch.java +++ b/subprojects/extTest/src/test/java/org/mockitousage/plugins/switcher/MyPluginSwitch.java @@ -14,6 +14,10 @@ public class MyPluginSwitch implements PluginSwitch { static List invokedFor = new LinkedList(); public boolean isEnabled(String pluginClassName) { + if (!pluginClassName.startsWith("org.mockitousage")) { + return false; + } + invokedFor.add(pluginClassName); return true; } From 91223f830552ce3bb5daf7095f4f30767e072b96 Mon Sep 17 00:00:00 2001 From: Ashley <73482956+ascopes@users.noreply.github.com> Date: Sat, 21 Jan 2023 21:08:22 +0000 Subject: [PATCH 09/12] Feat: reified mock overloads (#2882) Added reified mock overload methods to match the methods that consume an explicit Class object. The following methods have been added: - Mockito.mock(String, T...) - Sets the mock name. - Mockito.mock(Answer, T...) - Sets the default answer. - Mockito.mock(WithSettings, T...) - Provides custom settings. I have also added a case where passing null varargs in would result in a NullPointerException previously. Now, it will tell the user that they should not be providing these varargs at all. These overloads should not conflict with any existing usages of this API in the intended way, as the assumption is that a user probably isn't going to want to be mocking Mockito internals, Strings, or WithSettings objects anyway. If they do need to achieve this, then this is still accessible via the existing Mockito.mock(Class) methods anyway. --- src/main/java/org/mockito/Mockito.java | 59 +++++++++++++++++++--- src/test/java/org/mockito/MockitoTest.java | 44 ++++++++++++++++ 2 files changed, 97 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/mockito/Mockito.java b/src/main/java/org/mockito/Mockito.java index ff543e74b5..db2ca1096b 100644 --- a/src/main/java/org/mockito/Mockito.java +++ b/src/main/java/org/mockito/Mockito.java @@ -1924,21 +1924,68 @@ public class Mockito extends ArgumentMatchers { public static final Answer RETURNS_SELF = Answers.RETURNS_SELF; /** - * Creates mock object of requested class or interface. + * Creates a mock object of the requested class or interface. *

- * See examples in javadoc for {@link Mockito} class + * See examples in javadoc for the {@link Mockito} class. * - * @param reified don't pass any values to it. It's a trick to detect the class/interface you want to mock. - * @return mock object + * @param reified don't pass any values to it. It's a trick to detect the class/interface you + * want to mock. + * @return the mock object. * @since 4.9.0 */ @SafeVarargs public static T mock(T... reified) { - if (reified.length > 0) { + return mock(withSettings(), reified); + } + + /** + * Creates a mock object of the requested class or interface with the given default answer. + *

+ * See examples in javadoc for the {@link Mockito} class. + * + * @param defaultAnswer the default answer to use. + * @param reified don't pass any values to it. It's a trick to detect the class/interface you + * want to mock. + * @return the mock object. + */ + @SafeVarargs + public static T mock(@SuppressWarnings("rawtypes") Answer defaultAnswer, T... reified) { + return mock(withSettings().defaultAnswer(defaultAnswer), reified); + } + + /** + * Creates a mock object of the requested class or interface with the given name. + *

+ * See examples in javadoc for the {@link Mockito} class. + * + * @param name the mock name to use. + * @param reified don't pass any values to it. It's a trick to detect the class/interface you + * want to mock. + * @return the mock object. + */ + @SafeVarargs + public static T mock(String name, T... reified) { + return mock(withSettings().name(name).defaultAnswer(RETURNS_DEFAULTS), reified); + } + + /** + * Creates a mock object of the requested class or interface with the given settings. + *

+ * See examples in javadoc for the {@link Mockito} class. + * + * @param settings the mock settings to use. + * @param reified don't pass any values to it. It's a trick to detect the class/interface you + * want to mock. + * @return the mock object. + */ + @SafeVarargs + public static T mock(MockSettings settings, T... reified) { + if (reified == null || reified.length > 0) { throw new IllegalArgumentException( "Please don't pass any values here. Java will detect class automagically."); } - return mock(getClassOf(reified), withSettings()); + + return mock(getClassOf(reified), settings); } /** diff --git a/src/test/java/org/mockito/MockitoTest.java b/src/test/java/org/mockito/MockitoTest.java index 1ebbb89b80..1671280d0c 100644 --- a/src/test/java/org/mockito/MockitoTest.java +++ b/src/test/java/org/mockito/MockitoTest.java @@ -21,6 +21,7 @@ import org.mockito.exceptions.misusing.NullInsteadOfMockException; import org.mockito.internal.configuration.plugins.Plugins; import org.mockito.internal.creation.MockSettingsImpl; +import org.mockito.listeners.InvocationListener; import org.mockito.plugins.InlineMockMaker; @SuppressWarnings("unchecked") @@ -166,6 +167,49 @@ public void automaticallyDetectsClassToMock() { assertThat(mock.size()).isEqualTo(42); } + @Test + @SuppressWarnings({"DoNotMock", "DoNotMockAutoValue"}) + public void newMockMethod_shouldNotBeCalledWithNullParameters() { + assertThatThrownBy( + () -> { + Mockito.mock((Object[]) null); + }) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageStartingWith("Please don't pass any values here"); + } + + @Test + public void reifiedMockMethodWithNameSetsTheExpectedName() { + List mock = Mockito.mock("My super cool new mock"); + assertThat(mock).hasToString("My super cool new mock"); + } + + @Test + public void reifiedMockMethodWithDefaultAnswerSetsTheDefaultAnswer() { + abstract class Something { + abstract Something somethingElse(); + } + + Something something = Mockito.mock(Answers.RETURNS_SELF); + + assertThat(something.somethingElse()).isSameAs(something); + } + + @Test + public void reifiedMockMethodWithSettingsAppliesTheSettings() { + + InvocationListener invocationListener = Mockito.mock(InvocationListener.class); + + List mock = + Mockito.mock( + Mockito.withSettings() + .name("my name here") + .invocationListeners(invocationListener)); + + assertThat(mock).hasToString("my name here"); + Mockito.verify(invocationListener).reportInvocation(ArgumentMatchers.any()); + } + @Test @SuppressWarnings({"DoNotMock", "DoNotMockAutoValue"}) public void newMockMethod_shouldNotBeCalledWithParameters() { From 4775c67fe3569bbb735877e101b5f8a7889788f9 Mon Sep 17 00:00:00 2001 From: Andriy Redko Date: Tue, 24 Jan 2023 01:05:42 -0500 Subject: [PATCH 10/12] Clean up JDK-8 related code (#2883) Fixes #2879 Signed-off-by: Andriy Redko --- build.gradle | 2 +- .../InlineDelegateByteBuddyMockMaker.java | 4 +- .../bytebuddy/SubclassByteBuddyMockMaker.java | 4 +- .../internal/debugging/Java8LocationImpl.java | 59 ---- .../debugging/Java9PlusLocationImpl.java | 304 ------------------ .../internal/debugging/LocationFactory.java | 32 +- .../defaultanswers/ReturnsEmptyValues.java | 52 +-- .../mockito/internal/util/JavaEightUtil.java | 228 ------------- .../org/mockito/internal/util/Platform.java | 31 -- .../mockito/internal/util/PlatformTest.java | 32 +- subprojects/androidTest/androidTest.gradle | 2 +- .../kotlinReleaseCoroutinesTest.gradle | 12 + subprojects/kotlinTest/kotlinTest.gradle | 12 + 13 files changed, 61 insertions(+), 713 deletions(-) delete mode 100644 src/main/java/org/mockito/internal/debugging/Java8LocationImpl.java delete mode 100644 src/main/java/org/mockito/internal/debugging/Java9PlusLocationImpl.java delete mode 100644 src/main/java/org/mockito/internal/util/JavaEightUtil.java diff --git a/build.gradle b/build.gradle index f05c97fa31..92c56c1ed3 100644 --- a/build.gradle +++ b/build.gradle @@ -99,7 +99,7 @@ dependencies { testUtil sourceSets.test.output signature 'org.codehaus.mojo.signature:java18:1.0@signature' - signature 'net.sf.androidscents.signature:android-api-level-24:7.0_r2@signature' + signature 'net.sf.androidscents.signature:android-api-level-26:8.0.0_r2@signature' } animalsniffer { diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/InlineDelegateByteBuddyMockMaker.java b/src/main/java/org/mockito/internal/creation/bytebuddy/InlineDelegateByteBuddyMockMaker.java index 05512b8409..d40967f94e 100644 --- a/src/main/java/org/mockito/internal/creation/bytebuddy/InlineDelegateByteBuddyMockMaker.java +++ b/src/main/java/org/mockito/internal/creation/bytebuddy/InlineDelegateByteBuddyMockMaker.java @@ -447,9 +447,7 @@ private RuntimeException prettifyFailure( "IBM J9 VM", "Early IBM virtual machine are known to have issues with Mockito, please upgrade to an up-to-date version.\n", "Hotspot", - Platform.isJava8BelowUpdate45() - ? "Java 8 early builds have bugs that were addressed in Java 1.8.0_45, please update your JDK!\n" - : ""), + ""), Platform.describe(), "", "You are seeing this disclaimer because Mockito is configured to create inlined mocks.", diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassByteBuddyMockMaker.java b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassByteBuddyMockMaker.java index e8dcce229a..6bb74322b3 100644 --- a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassByteBuddyMockMaker.java +++ b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassByteBuddyMockMaker.java @@ -122,9 +122,7 @@ private RuntimeException prettifyFailure( "IBM J9 VM", "Early IBM virtual machine are known to have issues with Mockito, please upgrade to an up-to-date version.\n", "Hotspot", - Platform.isJava8BelowUpdate45() - ? "Java 8 early builds have bugs that were addressed in Java 1.8.0_45, please update your JDK!\n" - : ""), + ""), Platform.describe(), "", "Underlying exception : " + generationFailed), diff --git a/src/main/java/org/mockito/internal/debugging/Java8LocationImpl.java b/src/main/java/org/mockito/internal/debugging/Java8LocationImpl.java deleted file mode 100644 index e8ee387c0a..0000000000 --- a/src/main/java/org/mockito/internal/debugging/Java8LocationImpl.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2007 Mockito contributors - * This program is made available under the terms of the MIT License. - */ -package org.mockito.internal.debugging; - -import java.io.Serializable; - -import org.mockito.internal.exceptions.stacktrace.StackTraceFilter; -import org.mockito.invocation.Location; - -class Java8LocationImpl implements Location, Serializable { - - private static final long serialVersionUID = -9054861157390980624L; - // Limit the amount of objects being created, as this class is heavily instantiated: - private static final StackTraceFilter stackTraceFilter = new StackTraceFilter(); - - private String stackTraceLine; - private String sourceFile; - - public Java8LocationImpl(Throwable stackTraceHolder, boolean isInline) { - this(stackTraceFilter, stackTraceHolder, isInline); - } - - private Java8LocationImpl( - StackTraceFilter stackTraceFilter, Throwable stackTraceHolder, boolean isInline) { - computeStackTraceInformation(stackTraceFilter, stackTraceHolder, isInline); - } - - @Override - public String toString() { - return stackTraceLine; - } - - /** - * Eagerly compute the stacktrace line from the stackTraceHolder. Storing the Throwable is - * memory-intensive for tests that have large stacktraces and have a lot of invocations on - * mocks. - */ - private void computeStackTraceInformation( - StackTraceFilter stackTraceFilter, Throwable stackTraceHolder, boolean isInline) { - StackTraceElement filtered = stackTraceFilter.filterFirst(stackTraceHolder, isInline); - - // there are corner cases where exception can have a null or empty stack trace - // for example, a custom exception can override getStackTrace() method - if (filtered == null) { - this.stackTraceLine = "-> at <>"; - this.sourceFile = ""; - } else { - this.stackTraceLine = "-> at " + filtered; - this.sourceFile = filtered.getFileName(); - } - } - - @Override - public String getSourceFile() { - return sourceFile; - } -} diff --git a/src/main/java/org/mockito/internal/debugging/Java9PlusLocationImpl.java b/src/main/java/org/mockito/internal/debugging/Java9PlusLocationImpl.java deleted file mode 100644 index 219835513e..0000000000 --- a/src/main/java/org/mockito/internal/debugging/Java9PlusLocationImpl.java +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (c) 2007 Mockito contributors - * This program is made available under the terms of the MIT License. - */ -package org.mockito.internal.debugging; - -import org.mockito.exceptions.base.MockitoException; -import org.mockito.exceptions.stacktrace.StackTraceCleaner; -import org.mockito.exceptions.stacktrace.StackTraceCleaner.StackFrameMetadata; -import org.mockito.internal.configuration.plugins.Plugins; -import org.mockito.internal.exceptions.stacktrace.DefaultStackTraceCleaner; -import org.mockito.invocation.Location; - -import java.io.Serializable; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Collections; -import java.util.List; -import java.util.Set; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -class Java9PlusLocationImpl implements Location, Serializable { - private static final long serialVersionUID = 2954388321980069195L; - - private static final String UNEXPECTED_ERROR_SUFFIX = - "\nThis is unexpected and is likely due to a change in either Java's StackWalker or Reflection APIs." - + "\nIt's worth trying to upgrade to a newer version of Mockito, or otherwise to file a bug report."; - - private static final String STACK_WALKER = "java.lang.StackWalker"; - private static final String STACK_FRAME = STACK_WALKER + "$StackFrame"; - private static final String OPTION = STACK_WALKER + "$Option"; - private static final String SHOW_REFLECT_FRAMES = "SHOW_REFLECT_FRAMES"; - - /** - * This is an unfortunate buffer. Inside StackWalker, a buffer is created, which is resized by - * doubling. The resizing also allocates a tonne of StackFrame elements. If we traverse more than - * BUFFER_SIZE elements, the resulting resize can significantly affect the overall cost of the operation. - * If we traverse fewer than this number, we are inefficient. Empirically, 16 is enough stack frames - * for a simple stub+call operation to succeed without resizing, as measured on Java 11. - */ - private static final int BUFFER_SIZE = 16; - - private static final Class stackWalkerClazz = clazz(STACK_WALKER); - private static final Class stackFrameClazz = clazz(STACK_FRAME); - private static final Class optionClazz = clazz(OPTION); - - private static final Object stackWalker = stackWalker(); - private static final Method walk = walk(); - - private static final String PREFIX = "-> at "; - - private static final StackTraceCleaner CLEANER = - Plugins.getStackTraceCleanerProvider() - .getStackTraceCleaner(new DefaultStackTraceCleaner()); - - /** - * In Java, allocating lambdas is cheap, but not free. stream.map(this::doSomething) - * will allocate a Function object each time the function is called (although not - * per element). By assigning these Functions and Predicates to variables, we can - * avoid the memory allocation. - */ - private static final Function toStackFrameMetadata = - MetadataShim::new; - - private static final Predicate cleanerIsIn = CLEANER::isIn; - - private static final int FRAMES_TO_SKIP = framesToSkip(); - - private final StackFrameMetadata sfm; - private volatile String stackTraceLine; - - Java9PlusLocationImpl(boolean isInline) { - this.sfm = getStackFrame(isInline); - } - - @Override - public String getSourceFile() { - return sfm.getFileName(); - } - - @Override - public String toString() { - return stackTraceLine(); - } - - private String stackTraceLine() { - if (stackTraceLine == null) { - synchronized (this) { - if (stackTraceLine == null) { - stackTraceLine = PREFIX + sfm.toString(); - } - } - } - return stackTraceLine; - } - - private static StackFrameMetadata getStackFrame(boolean isInline) { - return stackWalk( - stream -> - stream.map(toStackFrameMetadata) - .skip(FRAMES_TO_SKIP) - .filter(cleanerIsIn) - .skip(isInline ? 1 : 0) - .findFirst() - .orElseThrow( - () -> new MockitoException(noStackTraceFailureMessage()))); - } - - private static boolean usingDefaultStackTraceCleaner() { - return CLEANER instanceof DefaultStackTraceCleaner; - } - - private static String noStackTraceFailureMessage() { - if (usingDefaultStackTraceCleaner()) { - return "Mockito could not find the first non-Mockito stack frame." - + UNEXPECTED_ERROR_SUFFIX; - } else { - String cleanerType = CLEANER.getClass().getName(); - String fmt = - "Mockito could not find the first non-Mockito stack frame. A custom stack frame cleaner \n" - + "(type %s) is in use and this has mostly likely filtered out all the relevant stack frames."; - return String.format(fmt, cleanerType); - } - } - - /** - * In order to trigger the stack walker, we create some reflective frames. These need to be skipped so as to - * ensure there are no non-Mockito frames at the top of the stack trace. - */ - private static int framesToSkip() { - return stackWalk( - stream -> { - List metadata = - stream.map(toStackFrameMetadata) - .map(StackFrameMetadata::getClassName) - .collect(Collectors.toList()); - return metadata.indexOf(Java9PlusLocationImpl.class.getName()); - }); - } - - @SuppressWarnings("unchecked") - private static T stackWalk(Function, T> function) { - try { - return (T) walk.invoke(stackWalker, function); - } catch (IllegalAccessException e) { - throw new MockitoException( - "Unexpected access exception while stack walking." + UNEXPECTED_ERROR_SUFFIX, - e); - } catch (InvocationTargetException e) { - throw new MockitoException(stackWalkFailureMessage()); - } - } - - private static String stackWalkFailureMessage() { - if (usingDefaultStackTraceCleaner()) { - return "Caught an unexpected exception while stack walking." + UNEXPECTED_ERROR_SUFFIX; - } else { - String className = CLEANER.getClass().getName(); - String fmt = - "Caught an unexpected exception while stack walking." - + "\nThis is likely caused by the custom stack trace cleaner in use (class %s)."; - return String.format(fmt, className); - } - } - - private static Method walk() { - try { - return stackWalkerClazz.getMethod("walk", Function.class); - } catch (NoSuchMethodException e) { - throw new RuntimeException(e); - } - } - - private static Class clazz(String name) { - try { - return Class.forName(name); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - private static Object stackWalker() { - try { - Set options = - Collections.singleton(Enum.valueOf((Class) optionClazz, SHOW_REFLECT_FRAMES)); - Method getInstance = - stackWalkerClazz.getDeclaredMethod("getInstance", Set.class, int.class); - return getInstance.invoke(null, options, BUFFER_SIZE); - } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { - throw new MockitoException( - "Mockito received an exception while trying to acquire a StackWalker." - + UNEXPECTED_ERROR_SUFFIX); - } - } - - private static final class MetadataShim implements StackFrameMetadata, Serializable { - private static final long serialVersionUID = 8491903719411428648L; - private static final Method getClassName = getter("getClassName"); - private static final Method getMethodName = getter("getMethodName"); - private static final Method getFileName = getter("getFileName"); - private static final Method getLineNumber = getter("getLineNumber"); - private static final Method toString = getter(Object.class, "toString"); - - private final Object stackFrame; - - private MetadataShim(Object stackFrame) { - this.stackFrame = stackFrame; - } - - @Override - public String getClassName() { - return (String) get(getClassName); - } - - @Override - public String getMethodName() { - return (String) get(getMethodName); - } - - @Override - public String getFileName() { - return (String) get(getFileName); - } - - @Override - public int getLineNumber() { - return (int) get(getLineNumber); - } - - @Override - public String toString() { - return (String) get(toString); - } - - /** - * Ensure that this type remains serializable. - */ - private Object writeReplace() { - return new SerializableShim(toStackTraceElement()); - } - - private StackTraceElement toStackTraceElement() { - try { - Method method = stackFrameClazz.getMethod("toStackTraceElement"); - return (StackTraceElement) method.invoke(stackFrame); - } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - private Object get(Method handle) { - try { - return handle.invoke(stackFrame); - } catch (InvocationTargetException | IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - private static Method getter(String name) { - return getter(stackFrameClazz, name); - } - - private static Method getter(Class clazz, String name) { - try { - return clazz.getDeclaredMethod(name); - } catch (Throwable t) { - throw new RuntimeException(t); - } - } - } - - private static final class SerializableShim implements StackFrameMetadata, Serializable { - private static final long serialVersionUID = 7908320459080898690L; - private final StackTraceElement ste; - - private SerializableShim(StackTraceElement ste) { - this.ste = ste; - } - - @Override - public String getClassName() { - return ste.getClassName(); - } - - @Override - public String getMethodName() { - return ste.getMethodName(); - } - - @Override - public String getFileName() { - return ste.getFileName(); - } - - @Override - public int getLineNumber() { - return ste.getLineNumber(); - } - } -} diff --git a/src/main/java/org/mockito/internal/debugging/LocationFactory.java b/src/main/java/org/mockito/internal/debugging/LocationFactory.java index daafddedaf..08e441e87a 100644 --- a/src/main/java/org/mockito/internal/debugging/LocationFactory.java +++ b/src/main/java/org/mockito/internal/debugging/LocationFactory.java @@ -7,8 +7,6 @@ import org.mockito.invocation.Location; public final class LocationFactory { - private static final Factory factory = createLocationFactory(); - private LocationFactory() {} public static Location create() { @@ -16,34 +14,6 @@ public static Location create() { } public static Location create(boolean inline) { - return factory.create(inline); - } - - private interface Factory { - Location create(boolean inline); - } - - private static Factory createLocationFactory() { - try { - Class.forName("java.lang.StackWalker"); - return new Java9PlusLocationFactory(); - } catch (ClassNotFoundException e) { - return new Java8LocationFactory(); - } - } - - private static final class Java8LocationFactory implements Factory { - @Override - public Location create(boolean inline) { - return new Java8LocationImpl(new Throwable(), inline); - } - } - - private static final class Java9PlusLocationFactory implements Factory { - - @Override - public Location create(boolean inline) { - return new Java9PlusLocationImpl(inline); - } + return new LocationImpl(inline); } } diff --git a/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsEmptyValues.java b/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsEmptyValues.java index ad8e7e2466..20e9d85afe 100644 --- a/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsEmptyValues.java +++ b/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsEmptyValues.java @@ -8,6 +8,8 @@ import static org.mockito.internal.util.ObjectMethodsGuru.isToStringMethod; import java.io.Serializable; +import java.time.Duration; +import java.time.Period; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -17,12 +19,20 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Optional; +import java.util.OptionalDouble; +import java.util.OptionalInt; +import java.util.OptionalLong; import java.util.Set; import java.util.SortedMap; import java.util.SortedSet; import java.util.TreeMap; import java.util.TreeSet; -import org.mockito.internal.util.JavaEightUtil; +import java.util.stream.DoubleStream; +import java.util.stream.IntStream; +import java.util.stream.LongStream; +import java.util.stream.Stream; + import org.mockito.internal.util.MockUtil; import org.mockito.internal.util.Primitives; import org.mockito.invocation.InvocationOnMock; @@ -129,26 +139,26 @@ Object returnValueFor(Class type) { return new TreeMap<>(); } else if (type == LinkedHashMap.class) { return new LinkedHashMap<>(); - } else if ("java.util.Optional".equals(type.getName())) { - return JavaEightUtil.emptyOptional(); - } else if ("java.util.OptionalDouble".equals(type.getName())) { - return JavaEightUtil.emptyOptionalDouble(); - } else if ("java.util.OptionalInt".equals(type.getName())) { - return JavaEightUtil.emptyOptionalInt(); - } else if ("java.util.OptionalLong".equals(type.getName())) { - return JavaEightUtil.emptyOptionalLong(); - } else if ("java.util.stream.Stream".equals(type.getName())) { - return JavaEightUtil.emptyStream(); - } else if ("java.util.stream.DoubleStream".equals(type.getName())) { - return JavaEightUtil.emptyDoubleStream(); - } else if ("java.util.stream.IntStream".equals(type.getName())) { - return JavaEightUtil.emptyIntStream(); - } else if ("java.util.stream.LongStream".equals(type.getName())) { - return JavaEightUtil.emptyLongStream(); - } else if ("java.time.Duration".equals(type.getName())) { - return JavaEightUtil.emptyDuration(); - } else if ("java.time.Period".equals(type.getName())) { - return JavaEightUtil.emptyPeriod(); + } else if (type == Optional.class) { + return Optional.empty(); + } else if (type == OptionalDouble.class) { + return OptionalDouble.empty(); + } else if (type == OptionalInt.class) { + return OptionalInt.empty(); + } else if (type == OptionalLong.class) { + return OptionalLong.empty(); + } else if (type == Stream.class) { + return Stream.empty(); + } else if (type == DoubleStream.class) { + return DoubleStream.empty(); + } else if (type == IntStream.class) { + return IntStream.empty(); + } else if (type == LongStream.class) { + return LongStream.empty(); + } else if (type == Duration.class) { + return Duration.ZERO; + } else if (type == Period.class) { + return Period.ZERO; } // Let's not care about the rest of collections. diff --git a/src/main/java/org/mockito/internal/util/JavaEightUtil.java b/src/main/java/org/mockito/internal/util/JavaEightUtil.java deleted file mode 100644 index 20c6e80c3b..0000000000 --- a/src/main/java/org/mockito/internal/util/JavaEightUtil.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2016 Mockito contributors - * This program is made available under the terms of the MIT License. - */ -package org.mockito.internal.util; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; - -import org.mockito.creation.instance.InstantiationException; - -/** - * Helper class to work with features that were introduced in Java versions after 1.5. - * This class uses reflection in most places to avoid coupling with a newer JDK. - */ -public final class JavaEightUtil { - - // No need for volatile, these optionals are already safe singletons. - private static Object emptyOptional; - private static Object emptyOptionalDouble; - private static Object emptyOptionalInt; - private static Object emptyOptionalLong; - private static Object emptyDuration; - private static Object emptyPeriod; - - private JavaEightUtil() { - // utility class - } - - /** - * Creates an empty Optional using reflection to stay backwards-compatible with older JDKs. - * - * @return an empty Optional. - */ - public static Object emptyOptional() { - // no need for double-checked locking - if (emptyOptional != null) { - return emptyOptional; - } - - return emptyOptional = invokeNullaryFactoryMethod("java.util.Optional", "empty"); - } - - /** - * Creates an empty OptionalDouble using reflection to stay backwards-compatible with older JDKs. - * - * @return an empty OptionalDouble. - */ - public static Object emptyOptionalDouble() { - // no need for double-checked locking - if (emptyOptionalDouble != null) { - return emptyOptionalDouble; - } - - return emptyOptionalDouble = - invokeNullaryFactoryMethod("java.util.OptionalDouble", "empty"); - } - - /** - * Creates an empty OptionalInt using reflection to stay backwards-compatible with older JDKs. - * - * @return an empty OptionalInt. - */ - public static Object emptyOptionalInt() { - // no need for double-checked locking - if (emptyOptionalInt != null) { - return emptyOptionalInt; - } - - return emptyOptionalInt = invokeNullaryFactoryMethod("java.util.OptionalInt", "empty"); - } - - /** - * Creates an empty OptionalLong using reflection to stay backwards-compatible with older JDKs. - * - * @return an empty OptionalLong. - */ - public static Object emptyOptionalLong() { - // no need for double-checked locking - if (emptyOptionalLong != null) { - return emptyOptionalLong; - } - - return emptyOptionalLong = invokeNullaryFactoryMethod("java.util.OptionalLong", "empty"); - } - - /** - * Creates an empty Stream using reflection to stay backwards-compatible with older JDKs. - * - * @return an empty Stream. - */ - public static Object emptyStream() { - // note: the empty stream can not be stored as a singleton. - return invokeNullaryFactoryMethod("java.util.stream.Stream", "empty"); - } - - /** - * Creates an empty DoubleStream using reflection to stay backwards-compatible with older JDKs. - * - * @return an empty DoubleStream. - */ - public static Object emptyDoubleStream() { - // note: the empty stream can not be stored as a singleton. - return invokeNullaryFactoryMethod("java.util.stream.DoubleStream", "empty"); - } - - /** - * Creates an empty IntStream using reflection to stay backwards-compatible with older JDKs. - * - * @return an empty IntStream. - */ - public static Object emptyIntStream() { - // note: the empty stream can not be stored as a singleton. - return invokeNullaryFactoryMethod("java.util.stream.IntStream", "empty"); - } - - /** - * Creates an empty LongStream using reflection to stay backwards-compatible with older JDKs. - * - * @return an empty LongStream. - */ - public static Object emptyLongStream() { - // note: the empty stream can not be stored as a singleton. - return invokeNullaryFactoryMethod("java.util.stream.LongStream", "empty"); - } - - /** - * Creates an empty Duration using reflection to stay backwards-compatible with older JDKs. - * - * @return an empty (ZERO) Duration. - */ - public static Object emptyDuration() { - // no need for double-checked locking - if (emptyDuration != null) { - return emptyDuration; - } - - return emptyDuration = getStaticFieldValue("java.time.Duration", "ZERO"); - } - - /** - * Creates an empty Period using reflection to stay backwards-compatible with older JDKs. - * - * @return an empty (ZERO) Period. - */ - public static Object emptyPeriod() { - // no need for double-checked locking - if (emptyPeriod != null) { - return emptyPeriod; - } - - return emptyPeriod = getStaticFieldValue("java.time.Period", "ZERO"); - } - - /** - * Invokes a nullary static factory method using reflection to stay backwards-compatible with older JDKs. - * - * @param fqcn The fully qualified class name of the type to be produced. - * @param methodName The name of the factory method. - * @return the object produced. - */ - private static Object invokeNullaryFactoryMethod(final String fqcn, final String methodName) { - try { - final Method method = getMethod(fqcn, methodName); - return method.invoke(null); - // any exception is really unexpected since the type name has - // already been verified - } catch (final Exception e) { - throw new InstantiationException( - String.format("Could not create %s#%s(): %s", fqcn, methodName, e), e); - } - } - - /** - * Gets a value of the classes' field using reflection to stay backwards-compatible with older JDKs. - * - * @param fqcn The fully qualified class name of the type to be produced. - * @param fieldName The name of th classes' field which value is going to be returned. - * @return the restored value. - */ - private static Object getStaticFieldValue(final String fqcn, final String fieldName) { - try { - final Class type = getClass(fqcn); - final Field field = type.getField(fieldName); - return field.get(null); - // any exception is really unexpected since the type name has - // already been verified - } catch (Exception e) { - throw new InstantiationException( - String.format("Could not get %s#%s(): %s", fqcn, fieldName, e), e); - } - } - - /** - * Returns the {@code Class} object associated with the class or interface with the given string name. - * - * @param fqcn The fully qualified class name of the type to be produced. - * @return the Class object for the class with the specified name. - */ - private static Class getClass(String fqcn) { - try { - return Class.forName(fqcn); - // any exception is really unexpected since the type name has - // already been verified - } catch (ClassNotFoundException e) { - throw new InstantiationException(String.format("Could not find %s: %s", fqcn, e), e); - } - } - - /** - * Returns a Method object that reflects the specified public member method of the class or interface represented by the fully qualified class name. - * - * @param fqcn The fully qualified class name of the type to be produced. - * @param methodName The name of the method. - * @param parameterClasses The list of parameters. - * @return The Method object that matches the specified name and parameterTypes. - */ - private static Method getMethod( - final String fqcn, final String methodName, final Class... parameterClasses) { - try { - final Class type = getClass(fqcn); - return type.getMethod(methodName, parameterClasses); - } catch (Exception e) { - throw new InstantiationException( - String.format("Could not find %s#%s(): %s", fqcn, methodName, e), e); - } - } -} diff --git a/src/main/java/org/mockito/internal/util/Platform.java b/src/main/java/org/mockito/internal/util/Platform.java index fde59fbbe9..6ff0378280 100644 --- a/src/main/java/org/mockito/internal/util/Platform.java +++ b/src/main/java/org/mockito/internal/util/Platform.java @@ -7,15 +7,9 @@ import static org.mockito.internal.util.StringUtil.join; import java.util.Locale; -import java.util.regex.Matcher; -import java.util.regex.Pattern; public abstract class Platform { - private static final Pattern JAVA_8_RELEASE_VERSION_SCHEME = - Pattern.compile("1\\.8\\.0_(\\d+)(?:-ea)?(?:-b\\d+)?"); - private static final Pattern JAVA_8_DEV_VERSION_SCHEME = - Pattern.compile("1\\.8\\.0b\\d+_u(\\d+)"); public static final String JAVA_VERSION = System.getProperty("java.specification.version"); public static final String JVM_VERSION = System.getProperty("java.runtime.version"); public static final String JVM_VENDOR = System.getProperty("java.vm.vendor"); @@ -68,31 +62,6 @@ public static String describe() { return description; } - public static boolean isJava8BelowUpdate45() { - if (JVM_VERSION == null) { - return false; - } else { - return isJava8BelowUpdate45(JVM_VERSION); - } - } - - static boolean isJava8BelowUpdate45(String jvmVersion) { - Matcher matcher = JAVA_8_RELEASE_VERSION_SCHEME.matcher(jvmVersion); - if (matcher.matches()) { - int update = Integer.parseInt(matcher.group(1)); - return update < 45; - } - - matcher = JAVA_8_DEV_VERSION_SCHEME.matcher(jvmVersion); - if (matcher.matches()) { - int update = Integer.parseInt(matcher.group(1)); - return update < 45; - } - - matcher = Pattern.compile("1\\.8\\.0-b\\d+").matcher(jvmVersion); - return matcher.matches(); - } - public static String warnForVM( String vmName1, String warnMessage1, String vmName2, String warnMessage2) { return warnForVM(JVM_NAME, vmName1, warnMessage1, vmName2, warnMessage2); diff --git a/src/test/java/org/mockito/internal/util/PlatformTest.java b/src/test/java/org/mockito/internal/util/PlatformTest.java index d4c453386d..42f59a1bc6 100644 --- a/src/test/java/org/mockito/internal/util/PlatformTest.java +++ b/src/test/java/org/mockito/internal/util/PlatformTest.java @@ -63,34 +63,6 @@ public void should_warn_for_jvm() throws Exception { .isEqualTo(""); } - @Test - public void should_parse_open_jdk_string_and_report_wether_below_or_nut_update_45() { - // Given - // Sources : - // - https://www.oracle.com/java/technologies/javase/versioning-naming.html - // - https://www.oracle.com/java/technologies/javase/jdk7-naming.html - // - https://www.oracle.com/java/technologies/javase/jdk8-naming.html - // - - // https://stackoverflow.com/questions/35844985/how-do-we-get-sr-and-fp-of-ibm-jre-using-java - // - - // https://www.ibm.com/support/knowledgecenter/SSYKE2_8.0.0/com.ibm.java.80.doc/user/build_number.html - Map versions = new HashMap<>(); - versions.put("1.8.0_92-b14", false); - versions.put("1.8.0-b24", true); - versions.put("1.8.0_5", true); - versions.put("1.8.0b5_u44", true); - versions.put("1.8.0b5_u92", false); - versions.put("1.7.0_4", false); - versions.put("1.4.0_03-b04", false); - versions.put("1.4.0_03-ea-b01", false); - versions.put("pxi3270_27sr4-20160303_03 (SR4)", false); - versions.put("pwi3260sr11-20120412_01 (SR11)", false); - versions.put("pwa6480sr1fp10-20150711_01 (SR1 FP10)", false); - versions.put("null", false); - - assertPlatformParsesCorrectlyVariousVersionScheme(versions); - } - @Test public void should_parse_open_jdk9_string() { // The tested method targets Java 8 but should be able to parse other Java version numbers @@ -140,9 +112,7 @@ public void should_parse_open_jdk9_string() { private void assertPlatformParsesCorrectlyVariousVersionScheme(Map versions) { for (Map.Entry version : versions.entrySet()) { - assertThat(Platform.isJava8BelowUpdate45(version.getKey())) - .describedAs(version.getKey()) - .isEqualTo(version.getValue()); + assertThat(version.getValue()).describedAs(version.getKey()).isEqualTo(false); } } } diff --git a/subprojects/androidTest/androidTest.gradle b/subprojects/androidTest/androidTest.gradle index 037b99cf72..2176b5052b 100644 --- a/subprojects/androidTest/androidTest.gradle +++ b/subprojects/androidTest/androidTest.gradle @@ -30,7 +30,7 @@ android { targetCompatibility JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '11' } } diff --git a/subprojects/kotlinReleaseCoroutinesTest/kotlinReleaseCoroutinesTest.gradle b/subprojects/kotlinReleaseCoroutinesTest/kotlinReleaseCoroutinesTest.gradle index a8512591ce..284b3bdfb7 100644 --- a/subprojects/kotlinReleaseCoroutinesTest/kotlinReleaseCoroutinesTest.gradle +++ b/subprojects/kotlinReleaseCoroutinesTest/kotlinReleaseCoroutinesTest.gradle @@ -1,3 +1,6 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + buildscript { repositories { mavenCentral() @@ -17,6 +20,15 @@ repositories { maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' } } +sourceCompatibility = 11 +targetCompatibility = 11 + +tasks.withType(KotlinCompile).configureEach { + compilerOptions { + jvmTarget = JvmTarget.JVM_11 + } +} + dependencies { testImplementation project(":") testImplementation libraries.junit4 diff --git a/subprojects/kotlinTest/kotlinTest.gradle b/subprojects/kotlinTest/kotlinTest.gradle index 55c8e8036f..99397def9f 100644 --- a/subprojects/kotlinTest/kotlinTest.gradle +++ b/subprojects/kotlinTest/kotlinTest.gradle @@ -1,3 +1,6 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + plugins { id 'org.jetbrains.kotlin.jvm' id 'java' @@ -7,6 +10,15 @@ description = "Kotlin tests for Mockito." apply from: "$rootDir/gradle/dependencies.gradle" +sourceCompatibility = 11 +targetCompatibility = 11 + +tasks.withType(KotlinCompile).configureEach { + compilerOptions { + jvmTarget = JvmTarget.JVM_11 + } +} + dependencies { testImplementation project(":") testImplementation libraries.junit4 From b47bab2970a7f9c782527ed90da2a6668f25409c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Jan 2023 20:11:54 +0100 Subject: [PATCH 11/12] Bump com.diffplug.spotless from 6.13.0 to 6.14.0 (#2888) Bumps com.diffplug.spotless from 6.13.0 to 6.14.0. --- updated-dependencies: - dependency-name: com.diffplug.spotless dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 92c56c1ed3..b08e20b591 100644 --- a/build.gradle +++ b/build.gradle @@ -20,7 +20,7 @@ buildscript { } plugins { - id 'com.diffplug.spotless' version '6.13.0' + id 'com.diffplug.spotless' version '6.14.0' id 'eclipse' id 'com.github.ben-manes.versions' version '0.44.0' id 'biz.aQute.bnd.builder' version '6.4.0' From 19ab3ea8389d215621b256e055987df204f400e4 Mon Sep 17 00:00:00 2001 From: Ashley <73482956+ascopes@users.noreply.github.com> Date: Sun, 29 Jan 2023 10:11:26 +0000 Subject: [PATCH 12/12] Fixes some mistakes and missing details in documentation (#2889) - Makes static mock verification and construction initialisers into functional interfaces, and adds some missing documentation notes. - Fixes a number of grammar/spelling typos. - Replaces an instance of a JavaDoc comment suggesting to use a deprecated method with a reference to the suggested replacement. - Adds a note about supporting chaining of Spy with InjectMocks into the InjectMocks documentation --- .../java/org/mockito/AdditionalAnswers.java | 2 +- src/main/java/org/mockito/ArgumentCaptor.java | 7 +- .../java/org/mockito/ArgumentMatcher.java | 10 +-- .../java/org/mockito/ArgumentMatchers.java | 16 ++-- src/main/java/org/mockito/Incubating.java | 7 ++ src/main/java/org/mockito/InjectMocks.java | 5 ++ src/main/java/org/mockito/MockSettings.java | 20 ++--- .../java/org/mockito/MockedConstruction.java | 33 ++++++++ src/main/java/org/mockito/MockedStatic.java | 9 ++ src/main/java/org/mockito/MockingDetails.java | 2 +- src/main/java/org/mockito/Mockito.java | 83 ++++++++++--------- .../java/org/mockito/MockitoFramework.java | 8 +- src/main/java/org/mockito/MockitoSession.java | 4 +- src/main/java/org/mockito/NotExtensible.java | 2 +- src/main/java/org/mockito/Spy.java | 4 +- .../configuration/IMockitoConfiguration.java | 4 +- .../internal/debugging/LoggingListener.java | 2 +- .../stubbing/answers/CallsRealMethods.java | 4 +- .../defaultanswers/ReturnsSmartNulls.java | 8 +- .../debugging/LoggingListenerTest.java | 4 +- 20 files changed, 146 insertions(+), 88 deletions(-) diff --git a/src/main/java/org/mockito/AdditionalAnswers.java b/src/main/java/org/mockito/AdditionalAnswers.java index 1ba790f1c0..63ab9bb483 100644 --- a/src/main/java/org/mockito/AdditionalAnswers.java +++ b/src/main/java/org/mockito/AdditionalAnswers.java @@ -276,7 +276,7 @@ public static Answer returnsArgAt(int position) { * This feature suffers from the same drawback as the spy. * The mock will call the delegate if you use regular when().then() stubbing style. * Since the real implementation is called this might have some side effects. - * Therefore you should use the doReturn|Throw|Answer|CallRealMethod stubbing style. Example: + * Therefore, you should use the doReturn|Throw|Answer|CallRealMethod stubbing style. Example: * *

      *   List listWithDelegate = mock(List.class, AdditionalAnswers.delegatesTo(awesomeList));
diff --git a/src/main/java/org/mockito/ArgumentCaptor.java b/src/main/java/org/mockito/ArgumentCaptor.java
index ed9e398f91..e9b347bd2e 100644
--- a/src/main/java/org/mockito/ArgumentCaptor.java
+++ b/src/main/java/org/mockito/ArgumentCaptor.java
@@ -35,12 +35,13 @@
  *
  * 

* Warning: it is recommended to use ArgumentCaptor with verification but not with stubbing. - * Using ArgumentCaptor with stubbing may decrease test readability because captor is created outside of assert (aka verify or 'then') block. - * Also it may reduce defect localization because if stubbed method was not called then no argument is captured. + * Using ArgumentCaptor with stubbing may decrease test readability because captor is created + * outside of assertion (aka verify or 'then') blocks. + * It may also reduce defect localization because if the stubbed method was not called, then no argument is captured. * *

* In a way ArgumentCaptor is related to custom argument matchers (see javadoc for {@link ArgumentMatcher} class). - * Both techniques can be used for making sure certain arguments were passed to mocks. + * Both techniques can be used for making sure certain arguments were passed to mock objects. * However, ArgumentCaptor may be a better fit if: *

    *
  • custom argument matcher is not likely to be reused
  • diff --git a/src/main/java/org/mockito/ArgumentMatcher.java b/src/main/java/org/mockito/ArgumentMatcher.java index 5d68132d82..3c8ccdea00 100644 --- a/src/main/java/org/mockito/ArgumentMatcher.java +++ b/src/main/java/org/mockito/ArgumentMatcher.java @@ -10,7 +10,7 @@ * and reduce the risk of version incompatibility. * Migration guide is included close to the bottom of this javadoc. *

    - * For non-trivial method arguments used in stubbing or verification, you have following options + * For non-trivial method arguments used in stubbing or verification, you have the following options * (in no particular order): *

      *
    • refactor the code so that the interactions with collaborators are easier to test with mocks. @@ -102,10 +102,10 @@ * *
    • *
    - * What option is right for you? If you don't mind compile dependency to hamcrest - * then option b) is probably right for you. - * Your choice should not have big impact and is fully reversible - - * you can choose different option in future (and refactor the code) + * What option is right for you? If you don't mind having a compile-time dependency for Hamcrest, + * then the second option is probably right for you. + * Your choice should not have a big impact and is fully reversible - + * you can choose different option in future (and refactor the code)! * * @param type of argument * @since 2.1.0 diff --git a/src/main/java/org/mockito/ArgumentMatchers.java b/src/main/java/org/mockito/ArgumentMatchers.java index 1d3f11136f..de87f298a1 100644 --- a/src/main/java/org/mockito/ArgumentMatchers.java +++ b/src/main/java/org/mockito/ArgumentMatchers.java @@ -914,7 +914,7 @@ public static T argThat(ArgumentMatcher matcher) { /** * Allows creating custom char argument matchers. - * + *

    * Note that {@link #argThat} will not work with primitive char matchers due to NullPointerException auto-unboxing caveat. *

    * See examples in javadoc for {@link ArgumentMatchers} class @@ -929,7 +929,7 @@ public static char charThat(ArgumentMatcher matcher) { /** * Allows creating custom boolean argument matchers. - * + *

    * Note that {@link #argThat} will not work with primitive boolean matchers due to NullPointerException auto-unboxing caveat. *

    * See examples in javadoc for {@link ArgumentMatchers} class @@ -944,7 +944,7 @@ public static boolean booleanThat(ArgumentMatcher matcher) { /** * Allows creating custom byte argument matchers. - * + *

    * Note that {@link #argThat} will not work with primitive byte matchers due to NullPointerException auto-unboxing caveat. *

    * See examples in javadoc for {@link ArgumentMatchers} class @@ -959,7 +959,7 @@ public static byte byteThat(ArgumentMatcher matcher) { /** * Allows creating custom short argument matchers. - * + *

    * Note that {@link #argThat} will not work with primitive short matchers due to NullPointerException auto-unboxing caveat. *

    * See examples in javadoc for {@link ArgumentMatchers} class @@ -974,7 +974,7 @@ public static short shortThat(ArgumentMatcher matcher) { /** * Allows creating custom int argument matchers. - * + *

    * Note that {@link #argThat} will not work with primitive int matchers due to NullPointerException auto-unboxing caveat. *

    * See examples in javadoc for {@link ArgumentMatchers} class @@ -989,7 +989,7 @@ public static int intThat(ArgumentMatcher matcher) { /** * Allows creating custom long argument matchers. - * + *

    * Note that {@link #argThat} will not work with primitive long matchers due to NullPointerException auto-unboxing caveat. *

    * See examples in javadoc for {@link ArgumentMatchers} class @@ -1004,7 +1004,7 @@ public static long longThat(ArgumentMatcher matcher) { /** * Allows creating custom float argument matchers. - * + *

    * Note that {@link #argThat} will not work with primitive float matchers due to NullPointerException auto-unboxing caveat. *

    * See examples in javadoc for {@link ArgumentMatchers} class @@ -1019,7 +1019,7 @@ public static float floatThat(ArgumentMatcher matcher) { /** * Allows creating custom double argument matchers. - * + *

    * Note that {@link #argThat} will not work with primitive double matchers due to NullPointerException auto-unboxing caveat. *

    * See examples in javadoc for {@link ArgumentMatchers} class diff --git a/src/main/java/org/mockito/Incubating.java b/src/main/java/org/mockito/Incubating.java index adf011abc7..ba209b3c41 100644 --- a/src/main/java/org/mockito/Incubating.java +++ b/src/main/java/org/mockito/Incubating.java @@ -5,6 +5,7 @@ package org.mockito; import java.lang.annotation.Documented; +import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -22,7 +23,13 @@ * and can change before release. * *

+ * + *

+ * Any components extending a class or interface annotated with this annotation should also + * be considered to be incubating, as the underlying implementation may be subject to future change + * before it is finalized. */ @Retention(RetentionPolicy.RUNTIME) +@Inherited @Documented public @interface Incubating {} diff --git a/src/main/java/org/mockito/InjectMocks.java b/src/main/java/org/mockito/InjectMocks.java index ea8f188985..ff412b8df6 100644 --- a/src/main/java/org/mockito/InjectMocks.java +++ b/src/main/java/org/mockito/InjectMocks.java @@ -158,6 +158,11 @@ * be it mocks/spies or real objects. *

* + *

+ * Elements annotated with this annotation can also be spied upon by also adding the {@link Spy} + * annotation to the element. + *

+ * * @see Mock * @see Spy * @see MockitoAnnotations#openMocks(Object) diff --git a/src/main/java/org/mockito/MockSettings.java b/src/main/java/org/mockito/MockSettings.java index 8d8a093e25..6958bcb347 100644 --- a/src/main/java/org/mockito/MockSettings.java +++ b/src/main/java/org/mockito/MockSettings.java @@ -43,7 +43,7 @@ *
* {@link MockSettings} has been introduced for two reasons. * Firstly, to make it easy to add another mock setting when the demand comes. - * Secondly, to enable combining together different mock settings without introducing zillions of overloaded mock() methods. + * Secondly, to enable combining different mock settings without introducing zillions of overloaded mock() methods. */ @NotExtensible public interface MockSettings extends Serializable { @@ -64,7 +64,7 @@ public interface MockSettings extends Serializable { * Baz baz = (Baz) foo; * * - * @param interfaces extra interfaces the should implement. + * @param interfaces extra interfaces the mock should implement. * @return settings instance so that you can fluently specify other settings */ MockSettings extraInterfaces(Class... interfaces); @@ -94,7 +94,7 @@ public interface MockSettings extends Serializable { * * Sets the instance that will be spied. Actually copies the internal fields of the passed instance to the mock. *

- * As usual you are going to read the partial mock warning: + * As usual, you are going to read the partial mock warning: * Object oriented programming is more or less about tackling complexity by dividing the complexity into separate, specific, SRPy objects. * How does partial mock fit into this paradigm? Well, it just doesn't... * Partial mock usually means that the complexity has been moved to a different method on the same object. @@ -133,10 +133,10 @@ public interface MockSettings extends Serializable { /** * Specifies default answers to interactions. - * It's quite advanced feature and typically you don't need it to write decent tests. - * However it can be helpful when working with legacy systems. + * It's quite advanced feature, and typically you don't need it to write decent tests. + * However, it can be helpful when working with legacy systems. *

- * It is the default answer so it will be used only when you don't stub the method call. + * It is the default answer, so it will be used only when you don't stub the method call. * *


      *   Foo mock = mock(Foo.class, withSettings().defaultAnswer(RETURNS_SMART_NULLS));
@@ -209,7 +209,7 @@ public interface MockSettings extends Serializable {
     /**
      * Add stubbing lookup listener to the mock object.
      *
-     * Multiple listeners may be added and they will be notified orderly.
+     * Multiple listeners may be added, and they will be notified in an orderly fashion.
      *
      * For use cases and more info see {@link StubbingLookupListener}.
      *
@@ -228,7 +228,7 @@ public interface MockSettings extends Serializable {
      * Registers a listener for method invocations on this mock. The listener is
      * notified every time a method on this mock is called.
      * 

- * Multiple listeners may be added and they will be notified in the order they were supplied. + * Multiple listeners may be added, and they will be notified in the order they were supplied. * * Example: *


@@ -247,7 +247,7 @@ public interface MockSettings extends Serializable {
      * See {@link VerificationStartedListener} on how such listener can be useful.
      * 

* When multiple listeners are added, they are notified in order they were supplied. - * There is no reason to supply multiple listeners but we wanted to keep the API + * There is no reason to supply multiple listeners, but we wanted to keep the API * simple and consistent with {@link #invocationListeners(InvocationListener...)}. *

* Throws exception when any of the passed listeners is null or when the entire vararg array is null. @@ -313,7 +313,7 @@ public interface MockSettings extends Serializable { MockSettings outerInstance(Object outerClassInstance); /** - * By default, Mockito makes an attempt to preserve all annotation meta data on the mocked + * By default, Mockito makes an attempt to preserve all annotation metadata on the mocked * type and its methods to mirror the mocked type as closely as possible. If this is not * desired, this option can be used to disable this behavior. * diff --git a/src/main/java/org/mockito/MockedConstruction.java b/src/main/java/org/mockito/MockedConstruction.java index 5c2ec2128d..ccf78c73a2 100644 --- a/src/main/java/org/mockito/MockedConstruction.java +++ b/src/main/java/org/mockito/MockedConstruction.java @@ -21,19 +21,52 @@ */ public interface MockedConstruction extends ScopedMock { + /** + * Get the constructed mocks. + * + * @return the constructed mocks. + */ List constructed(); + /** + * The context for a construction mock. + */ interface Context { int getCount(); + /** + * Get the constructor that is invoked during the mock creation. + * + * @return the constructor. + */ Constructor constructor(); + /** + * Get the arguments that were passed to the constructor. + * + * @return the arguments passed to the constructor, as a list. + */ List arguments(); } + /** + * Functional interface that consumes a newly created mock and the mock context. + *

+ * Used to attach behaviours to new mocks. + * + * @param the mock type. + */ + @FunctionalInterface interface MockInitializer { + /** + * Configure the mock. + * + * @param mock the newly created mock. + * @param context the mock context. + * @throws Throwable any exception that may be thrown. + */ void prepare(T mock, Context context) throws Throwable; } } diff --git a/src/main/java/org/mockito/MockedStatic.java b/src/main/java/org/mockito/MockedStatic.java index 9095556fd7..113bee2e3a 100644 --- a/src/main/java/org/mockito/MockedStatic.java +++ b/src/main/java/org/mockito/MockedStatic.java @@ -62,8 +62,17 @@ default void verify(Verification verification) { */ void verifyNoInteractions(); + /** + * Functional interface for a verification operation on a static mock. + */ + @FunctionalInterface interface Verification { + /** + * Apply the verification operation. + * + * @throws Throwable any exception that may be thrown. + */ void apply() throws Throwable; } } diff --git a/src/main/java/org/mockito/MockingDetails.java b/src/main/java/org/mockito/MockingDetails.java index c32e04e5c9..37a149100a 100644 --- a/src/main/java/org/mockito/MockingDetails.java +++ b/src/main/java/org/mockito/MockingDetails.java @@ -73,7 +73,7 @@ public interface MockingDetails { * What is 'stubbing'? * Stubbing is your when(x).then(y) declaration, e.g. configuring the mock to behave in a specific way, * when specific method with specific arguments is invoked on a mock. - * Typically stubbing is configuring mock to return X when method Y is invoked. + * Typically, stubbing is configuring mock to return X when method Y is invoked. *

* Why do you need to access stubbings of a mock? * In a normal workflow of creation clean tests, there is no need for this API. diff --git a/src/main/java/org/mockito/Mockito.java b/src/main/java/org/mockito/Mockito.java index db2ca1096b..428655e4a8 100644 --- a/src/main/java/org/mockito/Mockito.java +++ b/src/main/java/org/mockito/Mockito.java @@ -71,7 +71,7 @@ * 11. Stubbing with callbacks
* 12. doReturn()|doThrow()|doAnswer()|doNothing()|doCallRealMethod() family of methods
* 13. Spying on real objects
- * 14. Changing default return values of unstubbed invocations (Since 1.7)
+ * 14. Changing default return values of un-stubbed invocations (Since 1.7)
* 15. Capturing arguments for further assertions (Since 1.8.0)
* 16. Real partial mocks (Since 1.8.0)
* 17. Resetting mocks (Since 1.8.0)
@@ -226,7 +226,7 @@ * *

  • Stubbing can be overridden: for example common stubbing can go to * fixture setup but the test methods can override it. - * Please note that overridding stubbing is a potential code smell that points out too much stubbing
  • + * Please note that overriding stubbing is a potential code smell that points out too much stubbing * *
  • Once stubbed, the method will always return a stubbed value, regardless * of how many times it is called.
  • @@ -652,7 +652,7 @@ *
  • Mockito *does not* delegate calls to the passed real instance, instead it actually creates a copy of it. * So if you keep the real instance and interact with it, don't expect the spied to be aware of those interaction * and their effect on real instance state. - * The corollary is that when an *unstubbed* method is called *on the spy* but *not on the real instance*, + * The corollary is that when an *un-stubbed* method is called *on the spy* but *not on the real instance*, * you won't see any effects on the real instance. *
  • * @@ -665,7 +665,7 @@ * * * - *

    14. Changing default return values of unstubbed invocations (Since 1.7)

    + *

    14. Changing default return values of un-stubbed invocations (Since 1.7)

    * * You can create a mock with specified strategy for its return values. * It's quite an advanced feature and typically you don't need it to write decent tests. @@ -1671,9 +1671,9 @@ public class Mockito extends ArgumentMatchers { /** * The default Answer of every mock if the mock was not stubbed. * - * Typically it just returns some empty value. + * Typically, it just returns some empty value. *

    - * {@link Answer} can be used to define the return values of unstubbed invocations. + * {@link Answer} can be used to define the return values of un-stubbed invocations. *

    * This implementation first tries the global configuration and if there is no global configuration then * it will use a default answer that returns zeros, empty collections, nulls, etc. @@ -1683,12 +1683,14 @@ public class Mockito extends ArgumentMatchers { /** * Optional Answer to be used with {@link Mockito#mock(Class, Answer)}. *

    - * {@link Answer} can be used to define the return values of unstubbed invocations. + * {@link Answer} can be used to define the return values of un-stubbed invocations. *

    * This implementation can be helpful when working with legacy code. - * Unstubbed methods often return null. If your code uses the object returned by an unstubbed call you get a NullPointerException. + * Un-stubbed methods often return null. If your code uses the object returned by an un-stubbed call, + * you get a NullPointerException. * This implementation of Answer returns SmartNull instead of null. - * SmartNull gives nicer exception message than NPE because it points out the line where unstubbed method was called. You just click on the stack trace. + * SmartNull gives nicer exception messages than NPEs, because it points out the + * line where the un-stubbed method was called. You just click on the stack trace. *

    * ReturnsSmartNulls first tries to return ordinary values (zeros, empty collections, empty string, etc.) * then it tries to return SmartNull. If the return type is final then plain null is returned. @@ -1697,15 +1699,15 @@ public class Mockito extends ArgumentMatchers { *

    
          *   Foo mock = mock(Foo.class, RETURNS_SMART_NULLS);
          *
    -     *   //calling unstubbed method here:
    +     *   //calling un-stubbed method here:
          *   Stuff stuff = mock.getStuff();
          *
    -     *   //using object returned by unstubbed call:
    +     *   //using object returned by un-stubbed call:
          *   stuff.doSomething();
          *
          *   //Above doesn't yield NullPointerException this time!
          *   //Instead, SmartNullPointerException is thrown.
    -     *   //Exception's cause links to unstubbed mock.getStuff() - just click on the stack trace.
    +     *   //Exception's cause links to un-stubbed mock.getStuff() - just click on the stack trace.
          * 
    */ public static final Answer RETURNS_SMART_NULLS = Answers.RETURNS_SMART_NULLS; @@ -1713,7 +1715,7 @@ public class Mockito extends ArgumentMatchers { /** * Optional Answer to be used with {@link Mockito#mock(Class, Answer)} *

    - * {@link Answer} can be used to define the return values of unstubbed invocations. + * {@link Answer} can be used to define the return values of un-stubbed invocations. *

    * This implementation can be helpful when working with legacy code. *

    @@ -1814,14 +1816,14 @@ public class Mockito extends ArgumentMatchers { * Optional Answer to be used with {@link Mockito#mock(Class, Answer)} * *

    - * {@link Answer} can be used to define the return values of unstubbed invocations. + * {@link Answer} can be used to define the return values of un-stubbed invocations. *

    * This implementation can be helpful when working with legacy code. - * When this implementation is used, unstubbed methods will delegate to the real implementation. + * When this implementation is used, un-stubbed methods will delegate to the real implementation. * This is a way to create a partial mock object that calls real methods by default. *

    - * As usual you are going to read the partial mock warning: - * Object oriented programming is more less tackling complexity by dividing the complexity into separate, specific, SRPy objects. + * As usual, you are going to read the partial mock warning: + * Object oriented programming is more-or-less tackling complexity by dividing the complexity into separate, specific, SRPy objects. * How does partial mock fit into this paradigm? Well, it just doesn't... * Partial mock usually means that the complexity has been moved to a different method on the same object. * In most cases, this is not the way you want to design your application. @@ -2050,7 +2052,7 @@ public static MockingDetails mockingDetails(Object toInspect) { *

    See examples in javadoc for {@link Mockito} class

    * * @param classToMock class or interface to mock - * @param defaultAnswer default answer for unstubbed methods + * @param defaultAnswer default answer for un-stubbed methods * * @return mock object */ @@ -2061,7 +2063,7 @@ public static T mock(Class classToMock, Answer defaultAnswer) { /** * Creates a mock with some non-standard settings. *

    - * The number of configuration points for a mock grows + * The number of configuration points for a mock will grow, * so we need a fluent way to introduce new configuration without adding more and more overloaded Mockito.mock() methods. * Hence {@link MockSettings}. *

    
    @@ -2071,7 +2073,7 @@ public static  T mock(Class classToMock, Answer defaultAnswer) {
          * 
    * Use it carefully and occasionally. What might be reason your test needs non-standard mocks? * Is the code under test so complicated that it requires non-standard mocks? - * Wouldn't you prefer to refactor the code under test so it is testable in a simple way? + * Wouldn't you prefer to refactor the code under test, so that it is testable in a simple way? *

    * See also {@link Mockito#withSettings()} *

    @@ -2090,7 +2092,7 @@ public static T mock(Class classToMock, MockSettings mockSettings) { *

    * Real spies should be used carefully and occasionally, for example when dealing with legacy code. *

    - * As usual you are going to read the partial mock warning: + * As usual, you are going to read the partial mock warning: * Object oriented programming tackles complexity by dividing the complexity into separate, specific, SRPy objects. * How does partial mock fit into this paradigm? Well, it just doesn't... * Partial mock usually means that the complexity has been moved to a different method on the same object. @@ -2145,7 +2147,7 @@ public static T mock(Class classToMock, MockSettings mockSettings) { *

  • Mockito *does not* delegate calls to the passed real instance, instead it actually creates a copy of it. * So if you keep the real instance and interact with it, don't expect the spied to be aware of those interaction * and their effect on real instance state. - * The corollary is that when an *unstubbed* method is called *on the spy* but *not on the real instance*, + * The corollary is that when an *un-stubbed* method is called *on the spy* but *not on the real instance*, * you won't see any effects on the real instance.
  • * *
  • Watch out for final methods. @@ -2228,7 +2230,7 @@ private static Class getClassOf(T[] array) { * test or the mock will remain active on the current thread. *

    * Note: We recommend against mocking static methods of classes in the standard library or - * classes used by custom class loaders used to executed the block with the mocked class. A mock + * classes used by custom class loaders used to execute the block with the mocked class. A mock * maker might forbid mocking static methods of know classes that are known to cause problems. * Also, if a static method is a JVM-intrinsic, it cannot typically be mocked even if not * explicitly forbidden. @@ -2248,7 +2250,7 @@ public static MockedStatic mockStatic(Class classToMock) { * test or the mock will remain active on the current thread. *

    * Note: We recommend against mocking static methods of classes in the standard library or - * classes used by custom class loaders used to executed the block with the mocked class. A mock + * classes used by custom class loaders used to execute the block with the mocked class. A mock * maker might forbid mocking static methods of know classes that are known to cause problems. * Also, if a static method is a JVM-intrinsic, it cannot typically be mocked even if not * explicitly forbidden. @@ -2269,7 +2271,7 @@ public static MockedStatic mockStatic(Class classToMock, Answer defaul * test or the mock will remain active on the current thread. *

    * Note: We recommend against mocking static methods of classes in the standard library or - * classes used by custom class loaders used to executed the block with the mocked class. A mock + * classes used by custom class loaders used to execute the block with the mocked class. A mock * maker might forbid mocking static methods of know classes that are known to cause problems. * Also, if a static method is a JVM-intrinsic, it cannot typically be mocked even if not * explicitly forbidden. @@ -2290,7 +2292,7 @@ public static MockedStatic mockStatic(Class classToMock, String name) * test or the mock will remain active on the current thread. *

    * Note: We recommend against mocking static methods of classes in the standard library or - * classes used by custom class loaders used to executed the block with the mocked class. A mock + * classes used by custom class loaders used to execute the block with the mocked class. A mock * maker might forbid mocking static methods of know classes that are known to cause problems. * Also, if a static method is a JVM-intrinsic, it cannot typically be mocked even if not * explicitly forbidden. @@ -2358,7 +2360,7 @@ public static MockedConstruction mockConstruction(Class classToMock) { * See examples in javadoc for {@link Mockito} class * * @param classToMock non-abstract class of which constructions should be mocked. - * @param mockInitializer a callback to prepare a mock's methods after its instantiation. + * @param mockInitializer a callback to prepare the methods on a mock after its instantiation. * @return mock controller */ public static MockedConstruction mockConstruction( @@ -2408,7 +2410,7 @@ public static MockedConstruction mockConstruction( * * @param classToMock non-abstract class of which constructions should be mocked. * @param mockSettings the settings to use. - * @param mockInitializer a callback to prepare a mock's methods after its instantiation. + * @param mockInitializer a callback to prepare the methods on a mock after its instantiation. * @return mock controller */ public static MockedConstruction mockConstruction( @@ -2427,7 +2429,7 @@ public static MockedConstruction mockConstruction( * * @param classToMock non-abstract class of which constructions should be mocked. * @param mockSettingsFactory a function to create settings to use. - * @param mockInitializer a callback to prepare a mock's methods after its instantiation. + * @param mockInitializer a callback to prepare the methods on a mock after its instantiation. * @return mock controller */ public static MockedConstruction mockConstruction( @@ -2478,7 +2480,7 @@ public static MockedConstruction mockConstruction( *

    * Stubbing can be overridden: for example common stubbing can go to fixture * setup but the test methods can override it. - * Please note that overridding stubbing is a potential code smell that points out too much stubbing. + * Please note that overriding stubbing is a potential code smell that points out too much stubbing. *

    * Once stubbed, the method will always return stubbed value regardless * of how many times it is called. @@ -2630,7 +2632,7 @@ public static void clearInvocations(T... mocks) { * Some users who did a lot of classic, expect-run-verify mocking tend to use verifyNoMoreInteractions() very often, even in every test method. * verifyNoMoreInteractions() is not recommended to use in every test method. * verifyNoMoreInteractions() is a handy assertion from the interaction testing toolkit. Use it only when it's relevant. - * Abusing it leads to overspecified, less maintainable tests. + * Abusing it leads to over-specified, less maintainable tests. *

    * This method will also detect unverified invocations that occurred before the test method, * for example: in setUp(), @Before method or in constructor. @@ -2723,7 +2725,8 @@ public static Stubber doThrow(Class toBeThrown) { /** * Same as {@link #doThrow(Class)} but sets consecutive exception classes to be thrown. Remember to use - * doThrow() when you want to stub the void method to throw several exception of specified class. + * doThrow() when you want to stub the void method to throw several exceptions + * that are instances of the specified class. *

    * A new exception instance will be created for each method invocation. *

    @@ -2752,8 +2755,8 @@ public static Stubber doThrow( /** * Use doCallRealMethod() when you want to call the real implementation of a method. *

    - * As usual you are going to read the partial mock warning: - * Object oriented programming is more less tackling complexity by dividing the complexity into separate, specific, SRPy objects. + * As usual, you are going to read the partial mock warning: + * Object oriented programming is more-or-less tackling complexity by dividing the complexity into separate, specific, SRPy objects. * How does partial mock fit into this paradigm? Well, it just doesn't... * Partial mock usually means that the complexity has been moved to a different method on the same object. * In most cases, this is not the way you want to design your application. @@ -2891,7 +2894,7 @@ public static Stubber doNothing() { * * Above scenarios shows a tradeoff of Mockito's elegant syntax. Note that the scenarios are very rare, though. * Spying should be sporadic and overriding exception-stubbing is very rare. Not to mention that in general - * overridding stubbing is a potential code smell that points out too much stubbing. + * overriding stubbing is a potential code smell that points out too much stubbing. *

    * See examples in javadoc for {@link Mockito} class * @@ -2942,7 +2945,7 @@ public static Stubber doReturn(Object toBeReturned) { * * Above scenarios shows a trade-off of Mockito's elegant syntax. Note that the scenarios are very rare, though. * Spying should be sporadic and overriding exception-stubbing is very rare. Not to mention that in general - * overridding stubbing is a potential code smell that points out too much stubbing. + * overriding stubbing is a potential code smell that points out too much stubbing. *

    * See examples in javadoc for {@link Mockito} class * @@ -2993,7 +2996,7 @@ public static InOrder inOrder(Object... mocks) { * and provides other benefits. *

    * ignoreStubs() is sometimes useful when coupled with verifyNoMoreInteractions() or verification inOrder(). - * Helps avoiding redundant verification of stubbed calls - typically we're not interested in verifying stubs. + * Helps to avoid redundant verification of stubbed calls - typically we're not interested in verifying stubs. *

    * Warning, ignoreStubs() might lead to overuse of verifyNoMoreInteractions(ignoreStubs(...)); * Bear in mind that Mockito does not recommend bombarding every test with verifyNoMoreInteractions() @@ -3240,7 +3243,7 @@ public static VerificationWithTimeout timeout(long millis) { /** * Verification will be triggered after given amount of millis, allowing testing of async code. - * Useful when interactions with the mock object did not happened yet. + * Useful when interactions with the mock object have yet to occur. * Extensive use of {@code after()} method can be a code smell - there are better ways of testing concurrent code. *

    * Not yet implemented to work with InOrder verification. @@ -3400,7 +3403,7 @@ public static MockitoFramework framework() { /** * {@code MockitoSession} is an optional, highly recommended feature - * that helps driving cleaner tests by eliminating boilerplate code and adding extra validation. + * that drives writing cleaner tests by eliminating boilerplate code and adding extra validation. *

    * For more information, including use cases and sample code, see the javadoc for {@link MockitoSession}. * @@ -3422,7 +3425,7 @@ public static MockitoSessionBuilder mockitoSession() { * Most mocks in most tests don't need leniency and should happily prosper with {@link Strictness#STRICT_STUBS}. *

      *
    • If a specific stubbing needs to be lenient - use this method
    • - *
    • If a specific mock need to have stubbings lenient - use {@link MockSettings#lenient()}
    • + *
    • If a specific mock need to have lenient stubbings - use {@link MockSettings#strictness(Strictness)}
    • *
    • If a specific test method / test class needs to have all stubbings lenient * - configure strictness using our JUnit support ({@link MockitoJUnit} or Mockito Session ({@link MockitoSession})
    • * diff --git a/src/main/java/org/mockito/MockitoFramework.java b/src/main/java/org/mockito/MockitoFramework.java index ba814e6029..020186f052 100644 --- a/src/main/java/org/mockito/MockitoFramework.java +++ b/src/main/java/org/mockito/MockitoFramework.java @@ -26,11 +26,11 @@ public interface MockitoFramework { * Adds listener to Mockito. * For a list of supported listeners, see the interfaces that extend {@link MockitoListener}. *

      - * Listeners can be useful for engs that extend Mockito framework. + * Listeners can be useful for components that extend Mockito framework. * They are used in the implementation of unused stubbings warnings ({@link org.mockito.quality.MockitoHint}). *

      * Make sure you remove the listener when the job is complete, see {@link #removeListener(MockitoListener)}. - * Currently the listeners list is thread local so you need to remove listener from the same thread otherwise + * Currently, the listeners list is thread local, so you need to remove listener from the same thread otherwise * remove is ineffectual. * In typical scenarios, it is not a problem, because adding and removing listeners typically happens in the same thread. *

      @@ -56,7 +56,7 @@ public interface MockitoFramework { /** * When you add listener using {@link #addListener(MockitoListener)} make sure to remove it. - * Currently the listeners list is thread local so you need to remove listener from the same thread otherwise + * Currently, the listeners list is thread local, so you need to remove listener from the same thread otherwise * remove is ineffectual. * In typical scenarios, it is not a problem, because adding and removing listeners typically happens in the same thread. *

      @@ -92,7 +92,7 @@ public interface MockitoFramework { /** * Clears up internal state of all inline mocks. * This method is only meaningful if inline mock maker is in use. - * Otherwise this method is a no-op and need not be used. + * For all other intents and purposes, this method is a no-op and need not be used. *

      * This method is useful to tackle subtle memory leaks that are possible due to the nature of inline mocking * (issue #1619). diff --git a/src/main/java/org/mockito/MockitoSession.java b/src/main/java/org/mockito/MockitoSession.java index d3ad832c67..f87e07dcd4 100644 --- a/src/main/java/org/mockito/MockitoSession.java +++ b/src/main/java/org/mockito/MockitoSession.java @@ -17,12 +17,12 @@ /** * {@code MockitoSession} is an optional, highly recommended feature - * that helps driving cleaner tests by eliminating boilerplate code and adding extra validation. + * that drives writing cleaner tests by eliminating boilerplate code and adding extra validation. * If you already use {@link MockitoJUnitRunner} or {@link MockitoRule} * *you don't need* {@code MockitoSession} because it is used by the runner/rule. *

      * {@code MockitoSession} is a session of mocking, during which the user creates and uses Mockito mocks. - * Typically the session is an execution of a single test method. + * Typically, the session is an execution of a single test method. * {@code MockitoSession} initializes mocks, validates usage and detects incorrect stubbing. * When the session is started it must be concluded with {@link #finishMocking()} * otherwise {@link UnfinishedMockingSessionException} is triggered when the next session is created. diff --git a/src/main/java/org/mockito/NotExtensible.java b/src/main/java/org/mockito/NotExtensible.java index 39191ac481..f5110f5d57 100644 --- a/src/main/java/org/mockito/NotExtensible.java +++ b/src/main/java/org/mockito/NotExtensible.java @@ -19,7 +19,7 @@ * Public types are all types that are *not* under "org.mockito.internal.*" package. *

      * Absence of {@code NotExtensible} annotation on a type *does not* mean it is intended to be extended. - * The annotation has been introduced late and therefore it is not used frequently in the codebase. + * The annotation has been introduced late, and therefore it is not used frequently in the codebase. * Many public types from Mockito API are not intended for extension, even though they do not have this annotation applied. * * @since 2.10.0 diff --git a/src/main/java/org/mockito/Spy.java b/src/main/java/org/mockito/Spy.java index aa485a355d..fa5e6e5ad0 100644 --- a/src/main/java/org/mockito/Spy.java +++ b/src/main/java/org/mockito/Spy.java @@ -14,7 +14,7 @@ import org.mockito.junit.MockitoJUnitRunner; /** - * Allows shorthand wrapping of field instances in an spy object. + * Allows shorthand wrapping of field instances in a spy object. * *

      * Example: @@ -79,7 +79,7 @@ *

    • Mockito *does not* delegate calls to the passed real instance, instead it actually creates a copy of it. * So if you keep the real instance and interact with it, don't expect the spied to be aware of those interaction * and their effect on real instance state. - * The corollary is that when an *unstubbed* method is called *on the spy* but *not on the real instance*, + * The corollary is that when an *un-stubbed* method is called *on the spy* but *not on the real instance*, * you won't see any effects on the real instance.
    • * *
    • Watch out for final methods. diff --git a/src/main/java/org/mockito/configuration/IMockitoConfiguration.java b/src/main/java/org/mockito/configuration/IMockitoConfiguration.java index 53664940ea..6e16d350f1 100644 --- a/src/main/java/org/mockito/configuration/IMockitoConfiguration.java +++ b/src/main/java/org/mockito/configuration/IMockitoConfiguration.java @@ -13,7 +13,7 @@ * In most cases you don't really need to configure Mockito. For example in case of working with legacy code, * when you might want to have different 'mocking style' this interface might be helpful. * A reason of configuring Mockito might be if you disagree with the {@link org.mockito.Answers#RETURNS_DEFAULTS} - * unstubbed mocks return. + * un-stubbed mocks return. * *

      * To configure Mockito create exactly org.mockito.configuration.MockitoConfiguration class @@ -38,7 +38,7 @@ public interface IMockitoConfiguration { /** - * Allows configuring the default answers of unstubbed invocations + * Allows configuring the default answers of un-stubbed invocations *

      * See javadoc for {@link IMockitoConfiguration} */ diff --git a/src/main/java/org/mockito/internal/debugging/LoggingListener.java b/src/main/java/org/mockito/internal/debugging/LoggingListener.java index 6e0a645ce1..c5ebee4aa5 100644 --- a/src/main/java/org/mockito/internal/debugging/LoggingListener.java +++ b/src/main/java/org/mockito/internal/debugging/LoggingListener.java @@ -82,7 +82,7 @@ public String getStubbingInfo() { if (!unstubbedCalls.isEmpty()) { lines.add("[Mockito]"); lines.add( - "[Mockito] Unstubbed method invocations (perhaps missing stubbing in the test?):"); + "[Mockito] Un-stubbed method invocations (perhaps missing stubbing in the test?):"); lines.add("[Mockito]"); addOrderedList(lines, unstubbedCalls); } diff --git a/src/main/java/org/mockito/internal/stubbing/answers/CallsRealMethods.java b/src/main/java/org/mockito/internal/stubbing/answers/CallsRealMethods.java index bab007bbb0..ae16991af8 100644 --- a/src/main/java/org/mockito/internal/stubbing/answers/CallsRealMethods.java +++ b/src/main/java/org/mockito/internal/stubbing/answers/CallsRealMethods.java @@ -17,10 +17,10 @@ /** * Optional Answer that adds partial mocking support *

      - * {@link Answer} can be used to define the return values of unstubbed invocations. + * {@link Answer} can be used to define the return values of un-stubbed invocations. *

      * This implementation can be helpful when working with legacy code. - * When this implementation is used, unstubbed methods will delegate to the real implementation. + * When this implementation is used, un-stubbed methods will delegate to the real implementation. * This is a way to create a partial mock object that calls real methods by default. *

      * As usual you are going to read the partial mock warning: 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 6f6476d046..d538784a94 100644 --- a/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsSmartNulls.java +++ b/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsSmartNulls.java @@ -25,12 +25,12 @@ * Optional Answer that can be used with * {@link Mockito#mock(Class, Answer)} *

      - * This implementation can be helpful when working with legacy code. Unstubbed + * This implementation can be helpful when working with legacy code. Un-stubbed * methods often return null. If your code uses the object returned by an - * unstubbed call you get a NullPointerException. This implementation of + * un-stubbed call, you get a NullPointerException. This implementation of * Answer returns SmartNulls instead of nulls. * SmartNull gives nicer exception message than NPE because it points out the - * line where unstubbed method was called. You just click on the stack trace. + * line where un-stubbed method was called. You just click on the stack trace. *

      * ReturnsSmartNulls first tries to return ordinary return values (see * {@link ReturnsMoreEmptyValues}) then it tries to return SmartNull. If the @@ -90,7 +90,7 @@ private static class ThrowsSmartNullPointer implements Answer { @Override public Object answer(InvocationOnMock currentInvocation) throws Throwable { if (isToStringMethod(currentInvocation.getMethod())) { - return "SmartNull returned by this unstubbed method call on a mock:\n" + return "SmartNull returned by this un-stubbed method call on a mock:\n" + unstubbedInvocation; } else if (isMethodOf( MockAccess.class, currentInvocation.getMock(), currentInvocation.getMethod())) { diff --git a/src/test/java/org/mockito/internal/debugging/LoggingListenerTest.java b/src/test/java/org/mockito/internal/debugging/LoggingListenerTest.java index 54c5bec09d..a81aa98d2f 100644 --- a/src/test/java/org/mockito/internal/debugging/LoggingListenerTest.java +++ b/src/test/java/org/mockito/internal/debugging/LoggingListenerTest.java @@ -97,7 +97,7 @@ public void informs_about_various_kinds_of_stubs() { + "[Mockito]\n" + "[Mockito] 1. at com.FooTest:30\n" + "[Mockito]\n" - + "[Mockito] Unstubbed method invocations (perhaps missing stubbing in the test?):\n" + + "[Mockito] Un-stubbed method invocations (perhaps missing stubbing in the test?):\n" + "[Mockito]\n" + "[Mockito] 1. at com.Foo:96", listener.getStubbingInfo()); @@ -127,7 +127,7 @@ public void informs_about_unstubbed() { assertEquals( "[Mockito] Additional stubbing information (see javadoc for StubbingInfo class):\n" + "[Mockito]\n" - + "[Mockito] Unstubbed method invocations (perhaps missing stubbing in the test?):\n" + + "[Mockito] Un-stubbed method invocations (perhaps missing stubbing in the test?):\n" + "[Mockito]\n" + "[Mockito] 1. com.Foo:20", listener.getStubbingInfo());