Merge "Revert "Revert "Update mockito on AOSP to same version as on internal master"""
am: bf3ba3972a
Change-Id: I910f3bea560bbf2afcb2088f688fc221edca5d85
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 98b50ee..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-# IntelliJ IDEA
-.idea/
-*.iml
diff --git a/Android.bp b/Android.bp
index 09b4415..369a7ed 100644
--- a/Android.bp
+++ b/Android.bp
@@ -76,75 +76,15 @@
java_resource_dirs: ["subprojects/inline/src/main/resources"],
}
-// Main target for dependent projects. Bundles all the run-time dependencies
-// needed to run Mockito tests on the device.
-java_library_static {
- name: "mockito-target",
- no_framework_libs: true,
- static_libs: [
- "mockito-target-minus-junit4",
- "junit",
- ],
- sdk_version: "16",
-}
-
-// A mockito target that doesn't pull in junit. This is used to work around
-// issues caused by multiple copies of junit in the classpath, usually when a test
-// using mockito is run using android.test.runner.
-java_library_static {
- name: "mockito-target-minus-junit4",
- no_framework_libs: true,
- static_libs: [
- "mockito",
- "dexmaker",
- "dexmaker-mockmaker",
- "objenesis",
- ],
- libs: ["junit"],
- sdk_version: "16",
-
- java_version: "1.7",
-}
-
-// Main target for dependent projects. Bundles all the run-time dependencies
-// needed to run Mockito tests on the device.
-java_library_static {
- name: "mockito-target-inline",
- no_framework_libs: true,
- static_libs: [
- "mockito-target-inline-minus-junit4",
- "junit",
- ],
- sdk_version: "current",
-}
-
-// A mockito target that doesn't pull in junit. This is used to work around
-// issues caused by multiple copies of junit in the classpath, usually when a test
-// using mockito is run using android.test.runner.
-java_library_static {
- name: "mockito-target-inline-minus-junit4",
- no_framework_libs: true,
- static_libs: [
- "mockito",
- "dexmaker",
- "dexmaker-inline-mockmaker",
- "objenesis",
- ],
- libs: ["junit"],
- sdk_version: "current",
-
- java_version: "1.7",
-}
-
// Host prebuilt dependencies.
// ============================================================
java_import_host {
name: "mockito-byte-buddy",
- jars: ["lib/byte-buddy-1.7.9.jar"],
+ jars: ["lib/byte-buddy-1.8.10.jar"],
}
java_import_host {
name: "mockito-byte-buddy-agent",
- jars: ["lib/byte-buddy-agent-1.7.9.jar"],
+ jars: ["lib/byte-buddy-agent-1.8.10.jar"],
}
diff --git a/README.version b/README.version
index bbabbe6..aed32ab 100644
--- a/README.version
+++ b/README.version
@@ -1,5 +1,5 @@
URL: https://github.com/mockito/mockito
-Version: v2.16.0
+Version: v2.19.0
License: Apache 2.0
Description: Mockito is a mocking framework with a clean and simple API.
diff --git a/lib/byte-buddy-1.7.9-sources.jar b/lib/byte-buddy-1.7.9-sources.jar
deleted file mode 100644
index 0dd5b51..0000000
--- a/lib/byte-buddy-1.7.9-sources.jar
+++ /dev/null
Binary files differ
diff --git a/lib/byte-buddy-1.7.9.jar b/lib/byte-buddy-1.7.9.jar
deleted file mode 100644
index a348888..0000000
--- a/lib/byte-buddy-1.7.9.jar
+++ /dev/null
Binary files differ
diff --git a/lib/byte-buddy-1.8.10-sources.jar b/lib/byte-buddy-1.8.10-sources.jar
new file mode 100644
index 0000000..5e9f70c
--- /dev/null
+++ b/lib/byte-buddy-1.8.10-sources.jar
Binary files differ
diff --git a/lib/byte-buddy-1.8.10.jar b/lib/byte-buddy-1.8.10.jar
new file mode 100644
index 0000000..0edd796
--- /dev/null
+++ b/lib/byte-buddy-1.8.10.jar
Binary files differ
diff --git a/lib/byte-buddy-1.7.9.jar.txt b/lib/byte-buddy-1.8.10.jar.txt
similarity index 100%
rename from lib/byte-buddy-1.7.9.jar.txt
rename to lib/byte-buddy-1.8.10.jar.txt
diff --git a/lib/byte-buddy-agent-1.7.9-sources.jar b/lib/byte-buddy-agent-1.7.9-sources.jar
deleted file mode 100644
index 4940121..0000000
--- a/lib/byte-buddy-agent-1.7.9-sources.jar
+++ /dev/null
Binary files differ
diff --git a/lib/byte-buddy-agent-1.7.9.jar b/lib/byte-buddy-agent-1.7.9.jar
deleted file mode 100644
index 9fcfb59..0000000
--- a/lib/byte-buddy-agent-1.7.9.jar
+++ /dev/null
Binary files differ
diff --git a/lib/byte-buddy-agent-1.7.9.jar.txt b/lib/byte-buddy-agent-1.7.9.jar.txt
deleted file mode 100644
index e06d208..0000000
--- a/lib/byte-buddy-agent-1.7.9.jar.txt
+++ /dev/null
@@ -1,202 +0,0 @@
-Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "{}"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright {yyyy} {name of copyright owner}
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
diff --git a/lib/byte-buddy-agent-1.8.10-sources.jar b/lib/byte-buddy-agent-1.8.10-sources.jar
new file mode 100644
index 0000000..14cf977
--- /dev/null
+++ b/lib/byte-buddy-agent-1.8.10-sources.jar
Binary files differ
diff --git a/lib/byte-buddy-agent-1.8.10.jar b/lib/byte-buddy-agent-1.8.10.jar
new file mode 100644
index 0000000..4ca70ca
--- /dev/null
+++ b/lib/byte-buddy-agent-1.8.10.jar
Binary files differ
diff --git a/lib/byte-buddy-1.7.9.jar.txt b/lib/byte-buddy-agent-1.8.10.jar.txt
similarity index 100%
copy from lib/byte-buddy-1.7.9.jar.txt
copy to lib/byte-buddy-agent-1.8.10.jar.txt
diff --git a/src/main/java/org/mockito/Mockito.java b/src/main/java/org/mockito/Mockito.java
index b25dae5..620b7d4 100644
--- a/src/main/java/org/mockito/Mockito.java
+++ b/src/main/java/org/mockito/Mockito.java
@@ -99,6 +99,7 @@
* <a href="#42">42. (**new**) New API for integrations: listening on verification start events (Since 2.11.+)</a><br/>
* <a href="#43">43. (**new**) New API for integrations: <code>MockitoSession</code> is usable by testing frameworks (Since 2.15.+)</a><br/>
* <a href="#44">44. Deprecated <code>org.mockito.plugins.InstantiatorProvider</code> as it was leaking internal API. it was replaced by <code>org.mockito.plugins.InstantiatorProvider2 (Since 2.15.4)</code></a><br/>
+ * <a href="#45">45. (**new**) New JUnit Jupiter (JUnit5+) extension</a><br/>
* </b>
*
* <h3 id="0">0. <a class="meaningful_link" href="#mockito2" name="mockito2">Migrating to Mockito 2</a></h3>
@@ -1325,10 +1326,6 @@
* Currently, the feature is still optional as we wait for more feedback from the community.
*
* <p>
- * This feature is turned off by default because it is based on completely different mocking mechanism
- * that requires more feedback from the community.
- *
- * <p>
* This alternative mock maker which uses
* a combination of both Java instrumentation API and sub-classing rather than creating a new class to represent
* a mock. This way, it becomes possible to mock final types and methods.
@@ -1506,6 +1503,11 @@
* <p>{@link org.mockito.plugins.InstantiatorProvider} returned an internal API. Hence it was deprecated and replaced
* by {@link org.mockito.plugins.InstantiatorProvider2}. Old {@link org.mockito.plugins.InstantiatorProvider
* instantiator providers} will continue to work, but it is recommended to switch to the new API.</p>
+ *
+ * <h3 id="45">45. (**new**) <a class="meaningful_link" href="#junit5_mockito" name="junit5_mockito">New JUnit Jupiter (JUnit5+) extension</a></h3>
+ *
+ * For integration with JUnit Jupiter (JUnit5+), use the `org.mockito:mockito-junit-jupiter` artifact.
+ * For more information about the usage of the integration, see <a href="http://javadoc.io/page/org.mockito/mockito-junit-jupiter/latest/org/mockito/junit/jupiter/MockitoExtension.html">the JavaDoc of <code>MockitoExtension</code></a>.
*/
@SuppressWarnings("unchecked")
public class Mockito extends ArgumentMatchers {
@@ -1773,6 +1775,7 @@
* @param classToMock class or interface to mock
* @return mock object
*/
+ @CheckReturnValue
public static <T> T mock(Class<T> classToMock) {
return mock(classToMock, withSettings());
}
@@ -1792,6 +1795,7 @@
* @param name of the mock
* @return mock object
*/
+ @CheckReturnValue
public static <T> T mock(Class<T> classToMock, String name) {
return mock(classToMock, withSettings()
.name(name)
@@ -1810,6 +1814,7 @@
* @return A {@link org.mockito.MockingDetails} instance.
* @since 1.9.5
*/
+ @CheckReturnValue
public static MockingDetails mockingDetails(Object toInspect) {
return MOCKITO_CORE.mockingDetails(toInspect);
}
@@ -1833,6 +1838,7 @@
*
* @return mock object
*/
+ @CheckReturnValue
public static <T> T mock(Class<T> classToMock, Answer defaultAnswer) {
return mock(classToMock, withSettings().defaultAnswer(defaultAnswer));
}
@@ -1860,6 +1866,7 @@
* @param mockSettings additional mock settings
* @return mock object
*/
+ @CheckReturnValue
public static <T> T mock(Class<T> classToMock, MockSettings mockSettings) {
return MOCKITO_CORE.mock(classToMock, mockSettings);
}
@@ -1943,6 +1950,7 @@
* to spy on
* @return a spy of the real object
*/
+ @CheckReturnValue
public static <T> T spy(T object) {
return MOCKITO_CORE.mock((Class<T>) object.getClass(), withSettings()
.spiedInstance(object)
@@ -1977,6 +1985,7 @@
* @since 1.10.12
*/
@Incubating
+ @CheckReturnValue
public static <T> T spy(Class<T> classToSpy) {
return MOCKITO_CORE.mock(classToSpy, withSettings()
.useConstructor()
@@ -2521,6 +2530,7 @@
*
* @return InOrder object to be used to verify in order
*/
+ @CheckReturnValue
public static InOrder inOrder(Object... mocks) {
return MOCKITO_CORE.inOrder(mocks);
}
@@ -2604,6 +2614,7 @@
*
* @return verification mode
*/
+ @CheckReturnValue
public static VerificationMode times(int wantedNumberOfInvocations) {
return VerificationModeFactory.times(wantedNumberOfInvocations);
}
@@ -2625,6 +2636,7 @@
*
* @return verification mode
*/
+ @CheckReturnValue
public static VerificationMode never() {
return times(0);
}
@@ -2640,6 +2652,7 @@
*
* @return verification mode
*/
+ @CheckReturnValue
public static VerificationMode atLeastOnce() {
return VerificationModeFactory.atLeastOnce();
}
@@ -2656,6 +2669,7 @@
*
* @return verification mode
*/
+ @CheckReturnValue
public static VerificationMode atLeast(int minNumberOfInvocations) {
return VerificationModeFactory.atLeast(minNumberOfInvocations);
}
@@ -2672,6 +2686,7 @@
*
* @return verification mode
*/
+ @CheckReturnValue
public static VerificationMode atMost(int maxNumberOfInvocations) {
return VerificationModeFactory.atMost(maxNumberOfInvocations);
}
@@ -2689,6 +2704,7 @@
* @param wantedNumberOfInvocations number of invocations to verify
* @return verification mode
*/
+ @CheckReturnValue
public static VerificationMode calls( int wantedNumberOfInvocations ){
return VerificationModeFactory.calls( wantedNumberOfInvocations );
}
@@ -2709,6 +2725,7 @@
*
* @return verification mode
*/
+ @CheckReturnValue
public static VerificationMode only() {
return VerificationModeFactory.only();
}
@@ -2748,6 +2765,7 @@
*
* @return verification mode
*/
+ @CheckReturnValue
public static VerificationWithTimeout timeout(long millis) {
return new Timeout(millis, VerificationModeFactory.times(1));
}
@@ -2788,6 +2806,7 @@
*
* @return verification mode
*/
+ @CheckReturnValue
public static VerificationAfterDelay after(long millis) {
return new After(millis, VerificationModeFactory.times(1));
}
@@ -2871,6 +2890,7 @@
*
* @return mock settings instance with defaults.
*/
+ @CheckReturnValue
public static MockSettings withSettings() {
return new MockSettingsImpl().defaultAnswer(RETURNS_DEFAULTS);
}
@@ -2884,6 +2904,7 @@
* @return verification mode
* @since 2.1.0
*/
+ @CheckReturnValue
public static VerificationMode description(String description) {
return times(1).description(description);
}
@@ -2893,6 +2914,7 @@
* An instance of {@code MockingDetails} can be retrieved via {@link #mockingDetails(Object)}.
*/
@Deprecated
+ @CheckReturnValue
static MockitoDebugger debug() {
return new MockitoDebuggerImpl();
}
@@ -2903,6 +2925,7 @@
* @since 2.1.0
*/
@Incubating
+ @CheckReturnValue
public static MockitoFramework framework() {
return new DefaultMockitoFramework();
}
@@ -2916,6 +2939,7 @@
* @since 2.7.0
*/
@Incubating
+ @CheckReturnValue
public static MockitoSessionBuilder mockitoSession() {
return new DefaultMockitoSessionBuilder();
}
diff --git a/src/main/java/org/mockito/codegen/InjectionBase.java b/src/main/java/org/mockito/codegen/InjectionBase.java
new file mode 100644
index 0000000..b582c3b
--- /dev/null
+++ b/src/main/java/org/mockito/codegen/InjectionBase.java
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
+package org.mockito.codegen;
+
+/**
+ * This class is required to resolve a method handle lookup for the {@code org.mockito.codegen} package what requires a preexisting class for the package.
+ * By defining this class, the JVM (starting from Java 9) assures that this package is a part of the Mockito module such that we gain full access rights.
+ */
+public class InjectionBase {
+
+ private InjectionBase() {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/src/main/java/org/mockito/internal/configuration/SpyAnnotationEngine.java b/src/main/java/org/mockito/internal/configuration/SpyAnnotationEngine.java
index a80efbe..92d045d 100644
--- a/src/main/java/org/mockito/internal/configuration/SpyAnnotationEngine.java
+++ b/src/main/java/org/mockito/internal/configuration/SpyAnnotationEngine.java
@@ -140,7 +140,7 @@
for (Class<? extends Annotation> u : undesiredAnnotations) {
if (field.isAnnotationPresent(u)) {
throw unsupportedCombinationOfAnnotations(annotation.getSimpleName(),
- annotation.getClass().getSimpleName());
+ u.getSimpleName());
}
}
}
diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/InlineBytecodeGenerator.java b/src/main/java/org/mockito/internal/creation/bytebuddy/InlineBytecodeGenerator.java
index 7d60f6c..71ae6a6 100644
--- a/src/main/java/org/mockito/internal/creation/bytebuddy/InlineBytecodeGenerator.java
+++ b/src/main/java/org/mockito/internal/creation/bytebuddy/InlineBytecodeGenerator.java
@@ -15,6 +15,7 @@
import net.bytebuddy.description.method.ParameterDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.ClassFileLocator;
+import net.bytebuddy.dynamic.scaffold.MethodGraph;
import net.bytebuddy.dynamic.scaffold.TypeValidation;
import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.jar.asm.ClassVisitor;
@@ -29,7 +30,6 @@
import org.mockito.mock.SerializableMode;
import java.lang.instrument.ClassFileTransformer;
-import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.Instrumentation;
import java.lang.reflect.Modifier;
import java.security.ProtectionDomain;
@@ -44,6 +44,8 @@
public class InlineBytecodeGenerator implements BytecodeGenerator, ClassFileTransformer {
+ private static final String PRELOAD = "org.mockito.inline.preload";
+
@SuppressWarnings("unchecked")
static final Set<Class<?>> EXCLUDES = new HashSet<Class<?>>(Arrays.asList(Class.class,
Boolean.class,
@@ -62,34 +64,75 @@
private final WeakConcurrentSet<Class<?>> mocked;
- private final String identifier;
-
- private final MockMethodAdvice advice;
-
private final BytecodeGenerator subclassEngine;
+ private final AsmVisitorWrapper mockTransformer;
+
private volatile Throwable lastException;
public InlineBytecodeGenerator(Instrumentation instrumentation, WeakConcurrentMap<Object, MockMethodInterceptor> mocks) {
+ preload();
this.instrumentation = instrumentation;
byteBuddy = new ByteBuddy()
- .with(TypeValidation.DISABLED)
- .with(Implementation.Context.Disabled.Factory.INSTANCE);
+ .with(TypeValidation.DISABLED)
+ .with(Implementation.Context.Disabled.Factory.INSTANCE)
+ .with(MethodGraph.Compiler.ForDeclaredMethods.INSTANCE);
mocked = new WeakConcurrentSet<Class<?>>(WeakConcurrentSet.Cleaner.INLINE);
- identifier = RandomString.make();
- advice = new MockMethodAdvice(mocks, identifier);
+ String identifier = RandomString.make();
subclassEngine = new TypeCachingBytecodeGenerator(new SubclassBytecodeGenerator(withDefaultConfiguration()
- .withBinders(of(MockMethodAdvice.Identifier.class, identifier))
- .to(MockMethodAdvice.ForReadObject.class), isAbstract().or(isNative()).or(isToString())), false);
- MockMethodDispatcher.set(identifier, advice);
+ .withBinders(of(MockMethodAdvice.Identifier.class, identifier))
+ .to(MockMethodAdvice.ForReadObject.class), isAbstract().or(isNative()).or(isToString())), false);
+ mockTransformer = new AsmVisitorWrapper.ForDeclaredMethods()
+ .method(isVirtual()
+ .and(not(isBridge().or(isHashCode()).or(isEquals()).or(isDefaultFinalizer())))
+ .and(not(isDeclaredBy(nameStartsWith("java.")).<MethodDescription>and(isPackagePrivate()))),
+ Advice.withCustomMapping()
+ .bind(MockMethodAdvice.Identifier.class, identifier)
+ .to(MockMethodAdvice.class))
+ .method(isHashCode(),
+ Advice.withCustomMapping()
+ .bind(MockMethodAdvice.Identifier.class, identifier)
+ .to(MockMethodAdvice.ForHashCode.class))
+ .method(isEquals(),
+ Advice.withCustomMapping()
+ .bind(MockMethodAdvice.Identifier.class, identifier)
+ .to(MockMethodAdvice.ForEquals.class));
+ MockMethodDispatcher.set(identifier, new MockMethodAdvice(mocks, identifier));
instrumentation.addTransformer(this, true);
}
+ /**
+ * Mockito allows to mock about any type, including such types that we are relying on ourselves. This can cause a circularity:
+ * In order to check if an instance is a mock we need to look up if this instance is registered in the {@code mocked} set. But to look
+ * up this instance, we need to create key instances that rely on weak reference properties. Loading the later classes will happen before
+ * the key instances are completed what will cause Mockito to check if those key instances are themselves mocks what causes a loop which
+ * results in a circularity error. This is not normally a problem as we explicitly check if the instance that we investigate is one of
+ * our instance of which we hold a reference by reference equality what does not cause any code execution. But it seems like the load
+ * order plays a role here with unloaded types being loaded before we even get to check the mock instance property. To avoid this, we are
+ * making sure that crucuial JVM types are loaded before we create the first inline mock. Unfortunately, these types dependant on a JVM's
+ * implementation and we can only maintain types that we know of from well-known JVM implementations such as HotSpot and extend this list
+ * once we learn of further problematic types for future Java versions. To allow users to whitelist their own types, we do not also offer
+ * a property that allows running problematic tests before a new Mockito version can be released and that allows us to ask users to
+ * easily validate that whitelisting actually solves a problem as circularities could also be caused by other problems.
+ */
+ private static void preload() {
+ String preloads = System.getProperty(PRELOAD);
+ if (preloads == null) {
+ preloads = "java.lang.WeakPairMap,java.lang.WeakPairMap$Pair,java.lang.WeakPairMap$Pair$Weak";
+ }
+ for (String preload : preloads.split(",")) {
+ try {
+ Class.forName(preload, false, null);
+ } catch (ClassNotFoundException ignored) {
+ }
+ }
+ }
+
@Override
public <T> Class<? extends T> mockClass(MockFeatures<T> features) {
boolean subclassingRequired = !features.interfaces.isEmpty()
- || features.serializableMode != SerializableMode.NONE
- || Modifier.isAbstract(features.mockedType.getModifiers());
+ || features.serializableMode != SerializableMode.NONE
+ || Modifier.isAbstract(features.mockedType.getModifiers());
checkSupportedCombination(subclassingRequired, features);
@@ -157,29 +200,19 @@
String className,
Class<?> classBeingRedefined,
ProtectionDomain protectionDomain,
- byte[] classfileBuffer) throws IllegalClassFormatException {
+ byte[] classfileBuffer) {
if (classBeingRedefined == null
- || !mocked.contains(classBeingRedefined)
- || EXCLUDES.contains(classBeingRedefined)) {
+ || !mocked.contains(classBeingRedefined)
+ || EXCLUDES.contains(classBeingRedefined)) {
return null;
} else {
try {
return byteBuddy.redefine(classBeingRedefined, ClassFileLocator.Simple.of(classBeingRedefined.getName(), classfileBuffer))
- // Note: The VM erases parameter meta data from the provided class file (bug). We just add this information manually.
- .visit(new ParameterWritingVisitorWrapper(classBeingRedefined))
- .visit(Advice.withCustomMapping()
- .bind(MockMethodAdvice.Identifier.class, identifier)
- .to(MockMethodAdvice.class).on(isVirtual()
- .and(not(isBridge().or(isHashCode()).or(isEquals()).or(isDefaultFinalizer())))
- .and(not(isDeclaredBy(nameStartsWith("java.")).<MethodDescription>and(isPackagePrivate())))))
- .visit(Advice.withCustomMapping()
- .bind(MockMethodAdvice.Identifier.class, identifier)
- .to(MockMethodAdvice.ForHashCode.class).on(isHashCode()))
- .visit(Advice.withCustomMapping()
- .bind(MockMethodAdvice.Identifier.class, identifier)
- .to(MockMethodAdvice.ForEquals.class).on(isEquals()))
- .make()
- .getBytes();
+ // Note: The VM erases parameter meta data from the provided class file (bug). We just add this information manually.
+ .visit(new ParameterWritingVisitorWrapper(classBeingRedefined))
+ .visit(mockTransformer)
+ .make()
+ .getBytes();
} catch (Throwable throwable) {
lastException = throwable;
return null;
@@ -214,7 +247,7 @@
private final TypeDescription typeDescription;
private ParameterAddingClassVisitor(ClassVisitor cv, TypeDescription typeDescription) {
- super(Opcodes.ASM5, cv);
+ super(Opcodes.ASM6, cv);
this.typeDescription = typeDescription;
}
diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassBytecodeGenerator.java b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassBytecodeGenerator.java
index dc5c6e5..b659c73 100644
--- a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassBytecodeGenerator.java
+++ b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassBytecodeGenerator.java
@@ -38,6 +38,8 @@
class SubclassBytecodeGenerator implements BytecodeGenerator {
+ private static final String CODEGEN_PACKAGE = "org.mockito.codegen.";
+
private final SubclassLoader loader;
private final ByteBuddy byteBuddy;
@@ -46,6 +48,11 @@
private final Implementation readReplace;
private final ElementMatcher<? super MethodDescription> matcher;
+ private final Implementation dispatcher = to(DispatcherDefaultingToRealMethod.class);
+ private final Implementation hashCode = to(MockMethodInterceptor.ForHashCode.class);
+ private final Implementation equals = to(MockMethodInterceptor.ForEquals.class);
+ private final Implementation writeReplace = to(MockMethodInterceptor.ForWriteReplace.class);
+
public SubclassBytecodeGenerator() {
this(new SubclassInjectionLoader());
}
@@ -68,31 +75,32 @@
@Override
public <T> Class<? extends T> mockClass(MockFeatures<T> features) {
+ String name = nameFor(features.mockedType);
DynamicType.Builder<T> builder =
byteBuddy.subclass(features.mockedType)
- .name(nameFor(features.mockedType))
+ .name(name)
.ignoreAlso(isGroovyMethod())
.annotateType(features.stripAnnotations
? new Annotation[0]
: features.mockedType.getAnnotations())
.implement(new ArrayList<Type>(features.interfaces))
.method(matcher)
- .intercept(to(DispatcherDefaultingToRealMethod.class))
+ .intercept(dispatcher)
.transform(withModifiers(SynchronizationState.PLAIN))
.attribute(features.stripAnnotations
? MethodAttributeAppender.NoOp.INSTANCE
: INCLUDING_RECEIVER)
.method(isHashCode())
- .intercept(to(MockMethodInterceptor.ForHashCode.class))
+ .intercept(hashCode)
.method(isEquals())
- .intercept(to(MockMethodInterceptor.ForEquals.class))
+ .intercept(equals)
.serialVersionUid(42L)
.defineField("mockitoInterceptor", MockMethodInterceptor.class, PRIVATE)
.implement(MockAccess.class)
.intercept(FieldAccessor.ofBeanProperty());
if (features.serializableMode == SerializableMode.ACROSS_CLASSLOADERS) {
builder = builder.implement(CrossClassLoaderSerializableMock.class)
- .intercept(to(MockMethodInterceptor.ForWriteReplace.class));
+ .intercept(writeReplace);
}
if (readReplace != null) {
builder = builder.defineMethod("readObject", void.class, Visibility.PRIVATE)
@@ -118,7 +126,7 @@
.or(hasParameters(whereAny(hasType(isPackagePrivate())))));
}
return builder.make()
- .load(classLoader, loader.getStrategy(features.mockedType))
+ .load(classLoader, loader.resolveStrategy(features.mockedType, classLoader, name.startsWith(CODEGEN_PACKAGE)))
.getLoaded();
}
@@ -132,7 +140,7 @@
if (isComingFromJDK(type)
|| isComingFromSignedJar(type)
|| isComingFromSealedPackage(type)) {
- typeName = "codegen." + typeName;
+ typeName = CODEGEN_PACKAGE + type.getSimpleName();
}
return String.format("%s$%s$%d", typeName, "MockitoMock", Math.abs(random.nextInt()));
}
diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassInjectionLoader.java b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassInjectionLoader.java
index 20125f1..454dd8e 100644
--- a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassInjectionLoader.java
+++ b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassInjectionLoader.java
@@ -4,12 +4,104 @@
*/
package org.mockito.internal.creation.bytebuddy;
+import net.bytebuddy.dynamic.loading.ClassInjector;
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
+import org.mockito.codegen.InjectionBase;
+import org.mockito.exceptions.base.MockitoException;
+import org.mockito.internal.util.Platform;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import static org.mockito.internal.util.StringUtil.join;
class SubclassInjectionLoader implements SubclassLoader {
+ private static final String ERROR_MESSAGE = join("The current JVM does not support any class injection mechanism.",
+ "",
+ "Currently, Mockito supports injection via neither by method handle lookups or using sun.misc.Unsafe",
+ "Neither seems to be available on your current JVM.");
+
+ private final SubclassLoader loader;
+
+ SubclassInjectionLoader() {
+ if (!Boolean.getBoolean("org.mockito.internal.simulateJava11") && ClassInjector.UsingReflection.isAvailable()) {
+ this.loader = new WithReflection();
+ } else if (ClassInjector.UsingLookup.isAvailable()) {
+ this.loader = tryLookup();
+ } else {
+ throw new MockitoException(join(ERROR_MESSAGE, "", Platform.describe()));
+ }
+ }
+
+ private static SubclassLoader tryLookup() {
+ try {
+ Class<?> methodHandles = Class.forName("java.lang.invoke.MethodHandles");
+ Object lookup = methodHandles.getMethod("lookup").invoke(null);
+ Method privateLookupIn = methodHandles.getMethod("privateLookupIn", Class.class, Class.forName("java.lang.invoke.MethodHandles$Lookup"));
+ Object codegenLookup = privateLookupIn.invoke(null, InjectionBase.class, lookup);
+ return new WithLookup(lookup, codegenLookup, privateLookupIn);
+ } catch (Exception exception) {
+ throw new MockitoException(join(ERROR_MESSAGE, "", Platform.describe()), exception);
+ }
+ }
+
+ private static class WithReflection implements SubclassLoader {
+
+ @Override
+ public ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean codegen) {
+ return ClassLoadingStrategy.Default.INJECTION.with(codegen ? InjectionBase.class.getProtectionDomain() : mockedType.getProtectionDomain());
+ }
+ }
+
+ private static class WithLookup implements SubclassLoader {
+
+ private final Object lookup;
+
+ private final Object codegenLookup;
+
+ private final Method privateLookupIn;
+
+ WithLookup(Object lookup, Object codegenLookup, Method privateLookupIn) {
+ this.lookup = lookup;
+ this.codegenLookup = codegenLookup;
+ this.privateLookupIn = privateLookupIn;
+ }
+
+ @Override
+ public ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean codegen) {
+ if (codegen) {
+ return ClassLoadingStrategy.UsingLookup.of(codegenLookup);
+ } else if (classLoader != mockedType.getClassLoader()) {
+ return ClassLoadingStrategy.Default.WRAPPER.with(mockedType.getProtectionDomain());
+ } else {
+ try {
+ Object privateLookup;
+ try {
+ privateLookup = privateLookupIn.invoke(null, mockedType, lookup);
+ } catch (InvocationTargetException exception) {
+ if (exception.getCause() instanceof IllegalAccessException) {
+ return ClassLoadingStrategy.Default.WRAPPER.with(mockedType.getProtectionDomain());
+ } else {
+ throw exception.getCause();
+ }
+ }
+ return ClassLoadingStrategy.UsingLookup.of(privateLookup);
+ } catch (Throwable exception) {
+ throw new MockitoException(join(
+ "The Java module system prevents Mockito from defining a mock class in the same package as " + mockedType,
+ "",
+ "To overcome this, you must open and export the mocked type to Mockito.",
+ "Remember that you can also do so programmatically if the mocked class is defined by the same module as your test code",
+ exception
+ ));
+ }
+ }
+ }
+ }
+
@Override
- public ClassLoadingStrategy<ClassLoader> getStrategy(Class<?> mockedType) {
- return ClassLoadingStrategy.Default.INJECTION.with(mockedType.getProtectionDomain());
+ public ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean codegen) {
+ return loader.resolveStrategy(mockedType, classLoader, codegen);
}
}
diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassLoader.java b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassLoader.java
index 80b17ac..194c282 100644
--- a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassLoader.java
+++ b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassLoader.java
@@ -6,8 +6,18 @@
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
+/**
+ * A subclass loader is responsible for resolving a class loading strategy for a mock that is implemented as a subclass.
+ */
public interface SubclassLoader {
- ClassLoadingStrategy<ClassLoader> getStrategy(Class<?> mockedType);
-
+ /**
+ * Resolves a class loading strategy.
+ *
+ * @param mockedType The type being mocked.
+ * @param classLoader The class loader being used.
+ * @param codegen {@code true} if the mock is loaded in the {@code org.mockito.codegen} package.
+ * @return An appropriate class loading strategy.
+ */
+ ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean codegen);
}
diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/TypeCachingBytecodeGenerator.java b/src/main/java/org/mockito/internal/creation/bytebuddy/TypeCachingBytecodeGenerator.java
index 34c31fe..ea51edf 100644
--- a/src/main/java/org/mockito/internal/creation/bytebuddy/TypeCachingBytecodeGenerator.java
+++ b/src/main/java/org/mockito/internal/creation/bytebuddy/TypeCachingBytecodeGenerator.java
@@ -36,7 +36,7 @@
public Class<?> call() throws Exception {
return bytecodeGenerator.mockClass(params);
}
- }, classLoader == null ? BOOTSTRAP_LOCK : classLoader);
+ }, BOOTSTRAP_LOCK);
} catch (IllegalArgumentException exception) {
Throwable cause = exception.getCause();
if (cause instanceof RuntimeException) {
diff --git a/src/main/java/org/mockito/internal/exceptions/Reporter.java b/src/main/java/org/mockito/internal/exceptions/Reporter.java
index 57094c0..17823ff 100644
--- a/src/main/java/org/mockito/internal/exceptions/Reporter.java
+++ b/src/main/java/org/mockito/internal/exceptions/Reporter.java
@@ -5,9 +5,27 @@
package org.mockito.internal.exceptions;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
import org.mockito.exceptions.base.MockitoAssertionError;
import org.mockito.exceptions.base.MockitoException;
-import org.mockito.exceptions.misusing.*;
+import org.mockito.exceptions.misusing.CannotStubVoidMethodWithReturnValue;
+import org.mockito.exceptions.misusing.CannotVerifyStubOnlyMock;
+import org.mockito.exceptions.misusing.FriendlyReminderException;
+import org.mockito.exceptions.misusing.InvalidUseOfMatchersException;
+import org.mockito.exceptions.misusing.MissingMethodInvocationException;
+import org.mockito.exceptions.misusing.NotAMockException;
+import org.mockito.exceptions.misusing.NullInsteadOfMockException;
+import org.mockito.exceptions.misusing.PotentialStubbingProblem;
+import org.mockito.exceptions.misusing.RedundantListenerException;
+import org.mockito.exceptions.misusing.UnfinishedMockingSessionException;
+import org.mockito.exceptions.misusing.UnfinishedStubbingException;
+import org.mockito.exceptions.misusing.UnfinishedVerificationException;
+import org.mockito.exceptions.misusing.UnnecessaryStubbingException;
+import org.mockito.exceptions.misusing.WrongTypeOfReturnValue;
import org.mockito.exceptions.verification.NeverWantedButInvoked;
import org.mockito.exceptions.verification.NoInteractionsWanted;
import org.mockito.exceptions.verification.SmartNullPointerException;
@@ -28,12 +46,6 @@
import org.mockito.mock.MockName;
import org.mockito.mock.SerializableMode;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
import static org.mockito.internal.reporting.Pluralizer.pluralize;
import static org.mockito.internal.reporting.Pluralizer.were_exactly_x_interactions;
import static org.mockito.internal.util.StringUtil.join;
@@ -358,63 +370,71 @@
));
}
- public static MockitoAssertionError tooManyActualInvocations(int wantedCount, int actualCount, DescribedInvocation wanted, Location firstUndesired) {
- String message = createTooManyInvocationsMessage(wantedCount, actualCount, wanted, firstUndesired);
+ public static MockitoAssertionError tooManyActualInvocations(int wantedCount, int actualCount, DescribedInvocation wanted, List<Location> locations) {
+ String message = createTooManyInvocationsMessage(wantedCount, actualCount, wanted, locations);
return new TooManyActualInvocations(message);
}
private static String createTooManyInvocationsMessage(int wantedCount, int actualCount, DescribedInvocation wanted,
- Location firstUndesired) {
+ List<Location> invocations) {
return join(
wanted.toString(),
"Wanted " + pluralize(wantedCount) + ":",
new LocationImpl(),
- "But was " + pluralize(actualCount) + ". Undesired invocation:",
- firstUndesired,
+ "But was " + pluralize(actualCount) + ":",
+ createAllLocationsMessage(invocations),
""
);
}
- public static MockitoAssertionError neverWantedButInvoked(DescribedInvocation wanted, Location firstUndesired) {
+ public static MockitoAssertionError neverWantedButInvoked(DescribedInvocation wanted, List<Location> invocations) {
return new NeverWantedButInvoked(join(
wanted.toString(),
"Never wanted here:",
new LocationImpl(),
"But invoked here:",
- firstUndesired,
- ""
+ createAllLocationsMessage(invocations)
));
}
- public static MockitoAssertionError tooManyActualInvocationsInOrder(int wantedCount, int actualCount, DescribedInvocation wanted, Location firstUndesired) {
- String message = createTooManyInvocationsMessage(wantedCount, actualCount, wanted, firstUndesired);
+ public static MockitoAssertionError tooManyActualInvocationsInOrder(int wantedCount, int actualCount, DescribedInvocation wanted, List<Location> invocations) {
+ String message = createTooManyInvocationsMessage(wantedCount, actualCount, wanted, invocations);
return new VerificationInOrderFailure(join(
"Verification in order failure:" + message
));
}
- private static String createTooLittleInvocationsMessage(org.mockito.internal.reporting.Discrepancy discrepancy, DescribedInvocation wanted,
- Location lastActualInvocation) {
- String ending =
- (lastActualInvocation != null) ? lastActualInvocation + "\n" : "\n";
+ private static String createAllLocationsMessage(List<Location> locations) {
+ if (locations == null) {
+ return "\n";
+ }
+ StringBuilder sb = new StringBuilder();
+ for (Location location : locations) {
+ sb.append(location).append("\n");
+ }
+ return sb.toString();
+ }
+ private static String createTooLittleInvocationsMessage(org.mockito.internal.reporting.Discrepancy discrepancy,
+ DescribedInvocation wanted,
+ List<Location> locations) {
return join(
wanted.toString(),
"Wanted " + discrepancy.getPluralizedWantedCount() + (discrepancy.getWantedCount() == 0 ? "." : ":"),
new LocationImpl(),
"But was " + discrepancy.getPluralizedActualCount() + (discrepancy.getActualCount() == 0 ? "." : ":"),
- ending
+ createAllLocationsMessage(locations)
);
}
- public static MockitoAssertionError tooLittleActualInvocations(org.mockito.internal.reporting.Discrepancy discrepancy, DescribedInvocation wanted, Location lastActualLocation) {
- String message = createTooLittleInvocationsMessage(discrepancy, wanted, lastActualLocation);
+ public static MockitoAssertionError tooLittleActualInvocations(org.mockito.internal.reporting.Discrepancy discrepancy, DescribedInvocation wanted, List<Location> allLocations) {
+ String message = createTooLittleInvocationsMessage(discrepancy, wanted, allLocations);
return new TooLittleActualInvocations(message);
}
- public static MockitoAssertionError tooLittleActualInvocationsInOrder(org.mockito.internal.reporting.Discrepancy discrepancy, DescribedInvocation wanted, Location lastActualLocation) {
- String message = createTooLittleInvocationsMessage(discrepancy, wanted, lastActualLocation);
+ public static MockitoAssertionError tooLittleActualInvocationsInOrder(org.mockito.internal.reporting.Discrepancy discrepancy, DescribedInvocation wanted, List<Location> locations) {
+ String message = createTooLittleInvocationsMessage(discrepancy, wanted, locations);
return new VerificationInOrderFailure(join(
"Verification in order failure:" + message
diff --git a/src/main/java/org/mockito/internal/hamcrest/HamcrestArgumentMatcher.java b/src/main/java/org/mockito/internal/hamcrest/HamcrestArgumentMatcher.java
index f5216ee..9892422 100644
--- a/src/main/java/org/mockito/internal/hamcrest/HamcrestArgumentMatcher.java
+++ b/src/main/java/org/mockito/internal/hamcrest/HamcrestArgumentMatcher.java
@@ -7,6 +7,7 @@
import org.hamcrest.Matcher;
import org.hamcrest.StringDescription;
import org.mockito.ArgumentMatcher;
+import org.mockito.internal.matchers.VarargMatcher;
public class HamcrestArgumentMatcher<T> implements ArgumentMatcher<T> {
@@ -20,6 +21,10 @@
return this.matcher.matches(argument);
}
+ public boolean isVarargMatcher() {
+ return matcher instanceof VarargMatcher;
+ }
+
public String toString() {
//TODO SF add unit tests and integ test coverage for describeTo()
return StringDescription.toString(matcher);
diff --git a/src/main/java/org/mockito/internal/invocation/InvocationsFinder.java b/src/main/java/org/mockito/internal/invocation/InvocationsFinder.java
index 57c335f..260321b 100644
--- a/src/main/java/org/mockito/internal/invocation/InvocationsFinder.java
+++ b/src/main/java/org/mockito/internal/invocation/InvocationsFinder.java
@@ -138,6 +138,14 @@
return unverified;
}
+ public static List<Location> getAllLocations(List<Invocation> invocations) {
+ List<Location> locations = new LinkedList<Location>();
+ for (Invocation invocation : invocations) {
+ locations.add(invocation.getLocation());
+ }
+ return locations;
+ }
+
private static class RemoveNotMatching implements Filter<Invocation> {
private final MatchableInvocation wanted;
diff --git a/src/main/java/org/mockito/internal/invocation/MatcherApplicationStrategy.java b/src/main/java/org/mockito/internal/invocation/MatcherApplicationStrategy.java
index e085c25..e47156f 100644
--- a/src/main/java/org/mockito/internal/invocation/MatcherApplicationStrategy.java
+++ b/src/main/java/org/mockito/internal/invocation/MatcherApplicationStrategy.java
@@ -12,6 +12,7 @@
import java.util.List;
import org.mockito.ArgumentMatcher;
+import org.mockito.internal.hamcrest.HamcrestArgumentMatcher;
import org.mockito.internal.matchers.CapturingMatcher;
import org.mockito.internal.matchers.VarargMatcher;
import org.mockito.invocation.Invocation;
@@ -95,15 +96,19 @@
return ONE_MATCHER_PER_ARGUMENT;
}
- if (rawArguments == matcherCount && isLastMatcherVargargMatcher(matchers)) {
+ if (rawArguments == matcherCount && isLastMatcherVarargMatcher(matchers)) {
return MATCH_EACH_VARARGS_WITH_LAST_MATCHER;
}
return ERROR_UNSUPPORTED_NUMBER_OF_MATCHERS;
}
- private static boolean isLastMatcherVargargMatcher(final List<ArgumentMatcher<?>> matchers) {
- return lastMatcher(matchers) instanceof VarargMatcher;
+ private static boolean isLastMatcherVarargMatcher(final List<ArgumentMatcher<?>> matchers) {
+ ArgumentMatcher<?> argumentMatcher = lastMatcher(matchers);
+ if (argumentMatcher instanceof HamcrestArgumentMatcher<?>) {
+ return ((HamcrestArgumentMatcher<?>) argumentMatcher).isVarargMatcher();
+ }
+ return argumentMatcher instanceof VarargMatcher;
}
private static List<ArgumentMatcher<?>> appendLastMatcherNTimes(List<ArgumentMatcher<?>> matchers, int timesToAppendLastMatcher) {
diff --git a/src/main/java/org/mockito/internal/stubbing/BaseStubbing.java b/src/main/java/org/mockito/internal/stubbing/BaseStubbing.java
index ddb9a8d..6dd99cd 100644
--- a/src/main/java/org/mockito/internal/stubbing/BaseStubbing.java
+++ b/src/main/java/org/mockito/internal/stubbing/BaseStubbing.java
@@ -24,7 +24,8 @@
public OngoingStubbing<T> thenReturn(T value, T... values) {
OngoingStubbing<T> stubbing = thenReturn(value);
if (values == null) {
- // TODO below does not seem right
+ // For no good reason we're configuring null answer here
+ // This has been like that since forever, so let's keep it for compatibility (unless users complain)
return stubbing.thenReturn(null);
}
for (T v : values) {
@@ -65,7 +66,7 @@
@Override
public OngoingStubbing<T> thenThrow(Class<? extends Throwable> toBeThrown, Class<? extends Throwable>... nextToBeThrown) {
if (nextToBeThrown == null) {
- thenThrow((Class<Throwable>) null);
+ return thenThrow((Class<Throwable>) null);
}
OngoingStubbing<T> stubbing = thenThrow(toBeThrown);
for (Class<? extends Throwable> t : nextToBeThrown) {
diff --git a/src/main/java/org/mockito/internal/stubbing/StubberImpl.java b/src/main/java/org/mockito/internal/stubbing/StubberImpl.java
index b18d05d..7771c04 100644
--- a/src/main/java/org/mockito/internal/stubbing/StubberImpl.java
+++ b/src/main/java/org/mockito/internal/stubbing/StubberImpl.java
@@ -83,9 +83,9 @@
Throwable e;
try {
e = newInstance(toBeThrown);
- } catch (RuntimeException instanciationError) {
+ } catch (RuntimeException instantiationError) {
mockingProgress().reset();
- throw instanciationError;
+ throw instantiationError;
}
return doThrow(e);
}
diff --git a/src/main/java/org/mockito/internal/stubbing/answers/ThrowsException.java b/src/main/java/org/mockito/internal/stubbing/answers/ThrowsException.java
index 037520f..502e359 100644
--- a/src/main/java/org/mockito/internal/stubbing/answers/ThrowsException.java
+++ b/src/main/java/org/mockito/internal/stubbing/answers/ThrowsException.java
@@ -14,23 +14,36 @@
import static org.mockito.internal.exceptions.Reporter.cannotStubWithNullThrowable;
import static org.mockito.internal.exceptions.Reporter.checkedExceptionInvalid;
+/**
+ * An answer that always throws the same throwable.
+ */
public class ThrowsException implements Answer<Object>, ValidableAnswer, Serializable {
private static final long serialVersionUID = 1128820328555183980L;
private final Throwable throwable;
private final ConditionalStackTraceFilter filter = new ConditionalStackTraceFilter();
+ /**
+ * Creates a new answer always throwing the given throwable. If it is null,
+ * {@linkplain ValidableAnswer#validateFor(InvocationOnMock) answer validation}
+ * will fail.
+ */
public ThrowsException(Throwable throwable) {
this.throwable = throwable;
}
public Object answer(InvocationOnMock invocation) throws Throwable {
+ if (throwable == null) {
+ throw new IllegalStateException("throwable is null: " +
+ "you shall not call #answer if #validateFor fails!");
+ }
if (MockUtil.isMock(throwable)) {
throw throwable;
}
Throwable t = throwable.fillInStackTrace();
if (t == null) {
+ //Custom exceptions sometimes return null, see #866
throw throwable;
}
filter.filter(t);
diff --git a/src/main/java/org/mockito/internal/util/Primitives.java b/src/main/java/org/mockito/internal/util/Primitives.java
index 4d813e3..80dd0af 100644
--- a/src/main/java/org/mockito/internal/util/Primitives.java
+++ b/src/main/java/org/mockito/internal/util/Primitives.java
@@ -44,7 +44,7 @@
public static boolean isAssignableFromWrapper(Class<?> valueClass, Class<?> referenceType) {
if(isPrimitiveOrWrapper(valueClass) && isPrimitiveOrWrapper(referenceType)) {
- return Primitives.primitiveTypeOf(valueClass).isAssignableFrom(referenceType);
+ return Primitives.primitiveTypeOf(valueClass).isAssignableFrom(Primitives.primitiveTypeOf(referenceType));
}
return false;
}
diff --git a/src/main/java/org/mockito/internal/util/concurrent/WeakConcurrentMap.java b/src/main/java/org/mockito/internal/util/concurrent/WeakConcurrentMap.java
index b411a73..487d223 100644
--- a/src/main/java/org/mockito/internal/util/concurrent/WeakConcurrentMap.java
+++ b/src/main/java/org/mockito/internal/util/concurrent/WeakConcurrentMap.java
@@ -50,6 +50,7 @@
* @param key The key of the entry.
* @return The value of the entry or the default value if it did not exist.
*/
+ @SuppressWarnings("CollectionIncompatibleType")
public V get(K key) {
if (key == null) throw new NullPointerException();
V value = target.get(new LatentKey<K>(key));
@@ -69,6 +70,7 @@
* @param key The key of the entry.
* @return {@code true} if the key already defines a value.
*/
+ @SuppressWarnings("CollectionIncompatibleType")
public boolean containsKey(K key) {
if (key == null) throw new NullPointerException();
return target.containsKey(new LatentKey<K>(key));
@@ -88,6 +90,7 @@
* @param key The key of the entry.
* @return The removed entry or {@code null} if it does not exist.
*/
+ @SuppressWarnings("CollectionIncompatibleType")
public V remove(K key) {
if (key == null) throw new NullPointerException();
return target.remove(new LatentKey<K>(key));
diff --git a/src/main/java/org/mockito/internal/verification/checkers/AtLeastXNumberOfInvocationsChecker.java b/src/main/java/org/mockito/internal/verification/checkers/AtLeastXNumberOfInvocationsChecker.java
index 36e35a3..d0eb0b5 100644
--- a/src/main/java/org/mockito/internal/verification/checkers/AtLeastXNumberOfInvocationsChecker.java
+++ b/src/main/java/org/mockito/internal/verification/checkers/AtLeastXNumberOfInvocationsChecker.java
@@ -17,7 +17,7 @@
import static org.mockito.internal.invocation.InvocationMarker.markVerifiedInOrder;
import static org.mockito.internal.invocation.InvocationsFinder.findAllMatchingUnverifiedChunks;
import static org.mockito.internal.invocation.InvocationsFinder.findInvocations;
-import static org.mockito.internal.invocation.InvocationsFinder.getLastLocation;
+import static org.mockito.internal.invocation.InvocationsFinder.getAllLocations;
public class AtLeastXNumberOfInvocationsChecker {
@@ -26,8 +26,8 @@
int actualCount = actualInvocations.size();
if (wantedCount > actualCount) {
- Location lastLocation = getLastLocation(actualInvocations);
- throw tooLittleActualInvocations(new AtLeastDiscrepancy(wantedCount, actualCount), wanted, lastLocation);
+ List<Location> allLocations = getAllLocations(actualInvocations);
+ throw tooLittleActualInvocations(new AtLeastDiscrepancy(wantedCount, actualCount), wanted, allLocations);
}
markVerified(actualInvocations, wanted);
@@ -39,8 +39,8 @@
int actualCount = chunk.size();
if (wantedCount > actualCount) {
- Location lastLocation = getLastLocation(chunk);
- throw tooLittleActualInvocationsInOrder(new AtLeastDiscrepancy(wantedCount, actualCount), wanted, lastLocation);
+ List<Location> allLocations = getAllLocations(chunk);
+ throw tooLittleActualInvocationsInOrder(new AtLeastDiscrepancy(wantedCount, actualCount), wanted, allLocations);
}
markVerifiedInOrder(chunk, wanted, orderingContext);
diff --git a/src/main/java/org/mockito/internal/verification/checkers/NumberOfInvocationsChecker.java b/src/main/java/org/mockito/internal/verification/checkers/NumberOfInvocationsChecker.java
index 3fa340f..1dfc2f1 100644
--- a/src/main/java/org/mockito/internal/verification/checkers/NumberOfInvocationsChecker.java
+++ b/src/main/java/org/mockito/internal/verification/checkers/NumberOfInvocationsChecker.java
@@ -5,6 +5,7 @@
package org.mockito.internal.verification.checkers;
+import java.util.Arrays;
import java.util.List;
import org.mockito.internal.reporting.Discrepancy;
import org.mockito.internal.verification.api.InOrderContext;
@@ -22,7 +23,7 @@
import static org.mockito.internal.invocation.InvocationsFinder.findFirstMatchingUnverifiedInvocation;
import static org.mockito.internal.invocation.InvocationsFinder.findInvocations;
import static org.mockito.internal.invocation.InvocationsFinder.findMatchingChunk;
-import static org.mockito.internal.invocation.InvocationsFinder.getLastLocation;
+import static org.mockito.internal.invocation.InvocationsFinder.getAllLocations;
public class NumberOfInvocationsChecker {
@@ -34,16 +35,14 @@
int actualCount = actualInvocations.size();
if (wantedCount > actualCount) {
- Location lastInvocation = getLastLocation(actualInvocations);
- throw tooLittleActualInvocations(new Discrepancy(wantedCount, actualCount), wanted, lastInvocation);
+ List<Location> allLocations = getAllLocations(actualInvocations);
+ throw tooLittleActualInvocations(new Discrepancy(wantedCount, actualCount), wanted, allLocations);
}
if (wantedCount == 0 && actualCount > 0) {
- Location firstUndesired = actualInvocations.get(wantedCount).getLocation();
- throw neverWantedButInvoked(wanted, firstUndesired);
+ throw neverWantedButInvoked(wanted, getAllLocations(actualInvocations));
}
if (wantedCount < actualCount) {
- Location firstUndesired = actualInvocations.get(wantedCount).getLocation();
- throw tooManyActualInvocations(wantedCount, actualCount, wanted, firstUndesired);
+ throw tooManyActualInvocations(wantedCount, actualCount, wanted, getAllLocations(actualInvocations));
}
markVerified(actualInvocations, wanted);
@@ -55,12 +54,11 @@
int actualCount = chunk.size();
if (wantedCount > actualCount) {
- Location lastInvocation = getLastLocation(chunk);
- throw tooLittleActualInvocationsInOrder(new Discrepancy(wantedCount, actualCount), wanted, lastInvocation);
+ List<Location> allLocations = getAllLocations(chunk);
+ throw tooLittleActualInvocationsInOrder(new Discrepancy(wantedCount, actualCount), wanted, allLocations);
}
if (wantedCount < actualCount) {
- Location firstUndesired = chunk.get(wantedCount).getLocation();
- throw tooManyActualInvocationsInOrder(wantedCount, actualCount, wanted, firstUndesired);
+ throw tooManyActualInvocationsInOrder(wantedCount, actualCount, wanted, getAllLocations(chunk));
}
markVerifiedInOrder(chunk, wanted, context);
@@ -72,7 +70,7 @@
while( actualCount < wantedCount ){
Invocation next = findFirstMatchingUnverifiedInvocation(invocations, wanted, context );
if( next == null ){
- throw tooLittleActualInvocationsInOrder(new Discrepancy(wantedCount, actualCount), wanted, lastLocation );
+ throw tooLittleActualInvocationsInOrder(new Discrepancy(wantedCount, actualCount), wanted, Arrays.asList(lastLocation));
}
markVerified( next, wanted );
context.markVerified( next );
diff --git a/src/main/java/org/mockito/session/MockitoSessionBuilder.java b/src/main/java/org/mockito/session/MockitoSessionBuilder.java
index 474b7f9..b3a758b 100644
--- a/src/main/java/org/mockito/session/MockitoSessionBuilder.java
+++ b/src/main/java/org/mockito/session/MockitoSessionBuilder.java
@@ -47,7 +47,7 @@
* like {@link org.mockito.Mock}.
* <p>
* In most scenarios, you only need to init mocks on a single test class instance.
- * This method is useful for advanced framework integrations (like JUnit5), when a test uses multiple, e.g. nested, test class instances.
+ * This method is useful for advanced framework integrations (like JUnit Jupiter), when a test uses multiple, e.g. nested, test class instances.
* <p>
* This method calls {@link #initMocks(Object)} for each passed test class instance.
*
diff --git a/src/test/java/org/mockito/AnnotationsAreCopiedFromMockedTypeTest.java b/src/test/java/org/mockito/AnnotationsAreCopiedFromMockedTypeTest.java
index 7670183..1d9dfbb 100644
--- a/src/test/java/org/mockito/AnnotationsAreCopiedFromMockedTypeTest.java
+++ b/src/test/java/org/mockito/AnnotationsAreCopiedFromMockedTypeTest.java
@@ -63,7 +63,7 @@
@SuppressWarnings("unchecked")
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
for (Annotation firstParamAnnotation : firstParamAnnotations) {
- if (annotationClass.isAssignableFrom(firstParamAnnotation.getClass())) {
+ if (annotationClass.isAssignableFrom(firstParamAnnotation.annotationType())) {
return (T) firstParamAnnotation;
}
}
diff --git a/src/test/java/org/mockito/MockitoTest.java b/src/test/java/org/mockito/MockitoTest.java
index 3b96aff..ca8c4d4 100644
--- a/src/test/java/org/mockito/MockitoTest.java
+++ b/src/test/java/org/mockito/MockitoTest.java
@@ -25,11 +25,13 @@
assertThat(mockingProgress().pullOngoingStubbing()).isNull();
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test(expected=NotAMockException.class)
public void shouldValidateMockWhenVerifying() {
Mockito.verify("notMock");
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test(expected=NotAMockException.class)
public void shouldValidateMockWhenVerifyingWithExpectedNumberOfInvocations() {
Mockito.verify("notMock", times(19));
@@ -45,6 +47,7 @@
Mockito.verifyZeroInteractions("notMock");
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test(expected=NotAMockException.class)
public void shouldValidateMockWhenCreatingInOrderObject() {
Mockito.inOrder("notMock");
diff --git a/src/test/java/org/mockito/StaticMockingExperimentTest.java b/src/test/java/org/mockito/StaticMockingExperimentTest.java
index bb5e225..cc8a598 100644
--- a/src/test/java/org/mockito/StaticMockingExperimentTest.java
+++ b/src/test/java/org/mockito/StaticMockingExperimentTest.java
@@ -54,6 +54,7 @@
staticMethod = Foo.class.getDeclaredMethod("staticMethod", String.class);
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test
public void verify_static_method() throws Throwable {
//register staticMethod call on mock
@@ -81,6 +82,7 @@
handler.handle(differentArg);
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test
public void verification_failure_static_method() throws Throwable {
//register staticMethod call on mock
@@ -178,6 +180,7 @@
assertEquals(null, result2);
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test
public void verifying_new() throws Throwable {
Constructor<Foo> ctr = Foo.class.getConstructor(String.class);
diff --git a/src/test/java/org/mockito/internal/InvalidStateDetectionTest.java b/src/test/java/org/mockito/internal/InvalidStateDetectionTest.java
index c243e92..6baae82 100644
--- a/src/test/java/org/mockito/internal/InvalidStateDetectionTest.java
+++ b/src/test/java/org/mockito/internal/InvalidStateDetectionTest.java
@@ -46,6 +46,7 @@
super.resetState();
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test
public void shouldDetectUnfinishedStubbing() {
when(mock.simpleMethod());
@@ -70,6 +71,7 @@
detectsAndCleansUp(new OnDoAnswer(), UnfinishedStubbingException.class);
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test
public void shouldDetectUnfinishedDoAnswerStubbing() {
doAnswer(null);
@@ -94,6 +96,7 @@
detectsAndCleansUp(new OnDoAnswer(), UnfinishedStubbingException.class);
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test
public void shouldDetectUnfinishedVerification() {
verify(mock);
@@ -149,6 +152,7 @@
} catch (RuntimeException e) {}
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test
public void shouldCorrectStateAfterDetectingUnfinishedVerification() {
mock.simpleMethod();
@@ -167,36 +171,42 @@
}
private static class OnVerify implements DetectsInvalidState {
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
public void detect(IMethods mock) {
verify(mock);
}
}
private static class OnVerifyInOrder implements DetectsInvalidState {
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
public void detect(IMethods mock) {
inOrder(mock).verify(mock);
}
}
private static class OnVerifyZeroInteractions implements DetectsInvalidState {
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
public void detect(IMethods mock) {
verifyZeroInteractions(mock);
}
}
private static class OnVerifyNoMoreInteractions implements DetectsInvalidState {
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
public void detect(IMethods mock) {
verifyNoMoreInteractions(mock);
}
}
private static class OnDoAnswer implements DetectsInvalidState {
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
public void detect(IMethods mock) {
doAnswer(null);
}
}
private static class OnStub implements DetectsInvalidState {
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
public void detect(IMethods mock) {
when(mock);
}
@@ -209,12 +219,14 @@
}
private static class OnMockCreation implements DetectsInvalidState {
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
public void detect(IMethods mock) {
mock(IMethods.class);
}
}
private static class OnSpyCreation implements DetectsInvalidState {
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
public void detect(IMethods mock) {
spy(new Object());
}
diff --git a/src/test/java/org/mockito/internal/framework/DefaultMockitoFrameworkTest.java b/src/test/java/org/mockito/internal/framework/DefaultMockitoFrameworkTest.java
index 61646d7..0937b69 100644
--- a/src/test/java/org/mockito/internal/framework/DefaultMockitoFrameworkTest.java
+++ b/src/test/java/org/mockito/internal/framework/DefaultMockitoFrameworkTest.java
@@ -74,6 +74,7 @@
verifyNoMoreInteractions(listener);
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test
public void removes_creation_listener() {
//given creation listener is added
diff --git a/src/test/java/org/mockito/internal/invocation/InvocationsFinderTest.java b/src/test/java/org/mockito/internal/invocation/InvocationsFinderTest.java
index b07ece4..7172998 100644
--- a/src/test/java/org/mockito/internal/invocation/InvocationsFinderTest.java
+++ b/src/test/java/org/mockito/internal/invocation/InvocationsFinderTest.java
@@ -185,4 +185,15 @@
previous = InvocationsFinder.findPreviousVerifiedInOrder(invocations, context);
assertSame(simpleMethodInvocationTwo, previous);
}
+
+ @Test
+ public void shouldFindAllStackTraces() {
+ List<Location> all = InvocationsFinder.getAllLocations(invocations);
+ Assertions.assertThat(all).contains(simpleMethodInvocation.getLocation(), simpleMethodInvocationTwo.getLocation(), differentMethodInvocation.getLocation());
+ }
+
+ @Test
+ public void shouldNotFindLocationsForEmptyInvocationsList() {
+ Assertions.assertThat(InvocationsFinder.getAllLocations(Collections.<Invocation>emptyList())).isEmpty();
+ }
}
diff --git a/src/test/java/org/mockito/internal/invocation/MatcherApplicationStrategyTest.java b/src/test/java/org/mockito/internal/invocation/MatcherApplicationStrategyTest.java
index ce389b0..46a75eb 100644
--- a/src/test/java/org/mockito/internal/invocation/MatcherApplicationStrategyTest.java
+++ b/src/test/java/org/mockito/internal/invocation/MatcherApplicationStrategyTest.java
@@ -14,13 +14,17 @@
import java.util.ArrayList;
import java.util.List;
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
+import org.mockito.internal.hamcrest.HamcrestArgumentMatcher;
import org.mockito.internal.matchers.Any;
import org.mockito.internal.matchers.Equals;
import org.mockito.internal.matchers.InstanceOf;
+import org.mockito.internal.matchers.VarargMatcher;
import org.mockito.invocation.Invocation;
import org.mockitousage.IMethods;
import org.mockitoutil.TestBase;
@@ -186,6 +190,27 @@
recordAction.assertContainsExactly(ANY, ANY);
}
+ @Test
+ public void shouldMatchAnyVarargEvenIfMatcherIsWrappedInHamcrestMatcher() {
+ // given
+ invocation = varargs("1", "2");
+ HamcrestArgumentMatcher argumentMatcher = new HamcrestArgumentMatcher(new IntMatcher());
+ matchers = asList(argumentMatcher);
+
+ // when
+ getMatcherApplicationStrategyFor(invocation, matchers).forEachMatcherAndArgument(recordAction);
+
+ // then
+ recordAction.assertContainsExactly(argumentMatcher, argumentMatcher);
+ }
+
+ class IntMatcher extends BaseMatcher<Integer> implements VarargMatcher {
+ public boolean matches(Object o) {
+ return true;
+ }
+ public void describeTo(Description description) {}
+ }
+
private Invocation mixedVarargs(Object a, String... s) {
mock.mixedVarargs(a, s);
return getLastInvocation();
diff --git a/src/test/java/org/mockito/internal/junit/JUnitRuleTest.java b/src/test/java/org/mockito/internal/junit/JUnitRuleTest.java
index c4a8b53..7d5968d 100644
--- a/src/test/java/org/mockito/internal/junit/JUnitRuleTest.java
+++ b/src/test/java/org/mockito/internal/junit/JUnitRuleTest.java
@@ -32,12 +32,14 @@
throw new RuntimeException("foo");
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test
public void detects_invalid_mockito_usage_on_success() throws Throwable {
rule.expectFailure(UnfinishedStubbingException.class);
when(mock.simpleMethod());
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test
public void does_not_check_invalid_mockito_usage_on_failure() throws Throwable {
//This intended behavior is questionable
diff --git a/src/test/java/org/mockito/internal/progress/ThreadSafeMockingProgressTest.java b/src/test/java/org/mockito/internal/progress/ThreadSafeMockingProgressTest.java
index 5535eec..673ca10 100644
--- a/src/test/java/org/mockito/internal/progress/ThreadSafeMockingProgressTest.java
+++ b/src/test/java/org/mockito/internal/progress/ThreadSafeMockingProgressTest.java
@@ -34,6 +34,7 @@
assertNotNull(p.pullVerificationMode());
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test
public void shouldKnowWhenVerificationHasStarted() throws Exception {
//given
diff --git a/src/test/java/org/mockito/internal/stubbing/answers/ThrowsExceptionTest.java b/src/test/java/org/mockito/internal/stubbing/answers/ThrowsExceptionTest.java
index 8b553aa..2e71102 100644
--- a/src/test/java/org/mockito/internal/stubbing/answers/ThrowsExceptionTest.java
+++ b/src/test/java/org/mockito/internal/stubbing/answers/ThrowsExceptionTest.java
@@ -10,7 +10,9 @@
import org.junit.Test;
import org.mockito.exceptions.base.MockitoException;
import org.mockito.internal.invocation.InvocationBuilder;
+import org.mockito.invocation.Invocation;
+import static junit.framework.TestCase.fail;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
@@ -19,7 +21,7 @@
@Test
public void should_raise_wanted_throwable() throws Throwable {
try {
- new ThrowsException(new IllegalStateException("my dear throwable")).answer(new InvocationBuilder().method("canThrowException").toInvocation());
+ new ThrowsException(new IllegalStateException("my dear throwable")).answer(createMethodInvocation());
Assertions.fail("should have raised wanted exception");
} catch (Throwable throwable) {
assertThat(throwable).isInstanceOf(IllegalStateException.class).hasMessage("my dear throwable");
@@ -29,7 +31,7 @@
@Test
public void should_throw_mock_exception_without_stacktrace() throws Exception {
try {
- new ThrowsException(mock(Exception.class)).answer(new InvocationBuilder().method("canThrowException").toInvocation());
+ new ThrowsException(mock(Exception.class)).answer(createMethodInvocation());
Assertions.fail("should have raised wanted exception");
} catch (Throwable throwable) {
assertThat(throwable.getStackTrace()).describedAs("no stack trace, it's mock").isNull();
@@ -46,7 +48,7 @@
try {
// when
- new ThrowsException(throwableToRaise).answer(new InvocationBuilder().method("canThrowException").toInvocation());
+ new ThrowsException(throwableToRaise).answer(createMethodInvocation());
Assertions.fail("should have raised wanted exception");
} catch (Throwable throwable) {
// then
@@ -59,24 +61,42 @@
@Test
public void should_invalidate_null_throwable() throws Throwable {
try {
- new ThrowsException(null).validateFor(new InvocationBuilder().toInvocation());
+ Invocation invocation = createMethodInvocation();
+ new ThrowsException(null).validateFor(invocation);
Assertions.fail("should have raised a MockitoException");
} catch (MockitoException expected) {}
}
@Test
+ public void should_throw_illegal_state_exception_if_null_answer() throws Throwable {
+ Invocation invocation = createMethodInvocation();
+ try {
+ new ThrowsException(null).answer(invocation);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ }
+
+ @Test
public void should_pass_proper_checked_exception() throws Throwable {
- new ThrowsException(new CharacterCodingException()).validateFor(new InvocationBuilder().method("canThrowException").toInvocation());
+ new ThrowsException(new CharacterCodingException()).validateFor(createMethodInvocation());
}
@Test(expected = MockitoException.class)
public void should_fail_invalid_checked_exception() throws Throwable {
- new ThrowsException(new IOException()).validateFor(new InvocationBuilder().method("canThrowException").toInvocation());
+ new ThrowsException(new IOException()).validateFor(createMethodInvocation());
}
@Test
public void should_pass_RuntimeExceptions() throws Throwable {
- new ThrowsException(new Error()).validateFor(new InvocationBuilder().method("canThrowException").toInvocation());
- new ThrowsException(new RuntimeException()).validateFor(new InvocationBuilder().method("canThrowException").toInvocation());
+ new ThrowsException(new Error()).validateFor(createMethodInvocation());
+ new ThrowsException(new RuntimeException()).validateFor(createMethodInvocation());
+ }
+
+ /** Creates Invocation of a "canThrowException" method call. */
+ private static Invocation createMethodInvocation() {
+ return new InvocationBuilder()
+ .method("canThrowException")
+ .toInvocation();
}
}
diff --git a/src/test/java/org/mockito/internal/stubbing/defaultanswers/ReturnsEmptyValuesTest.java b/src/test/java/org/mockito/internal/stubbing/defaultanswers/ReturnsEmptyValuesTest.java
index 945cf08..68fbaf5 100644
--- a/src/test/java/org/mockito/internal/stubbing/defaultanswers/ReturnsEmptyValuesTest.java
+++ b/src/test/java/org/mockito/internal/stubbing/defaultanswers/ReturnsEmptyValuesTest.java
@@ -74,6 +74,7 @@
assertTrue(result != (Object) 0);
}
+ @SuppressWarnings("SelfComparison")
@Test
public void should_return_zero_if_mock_is_compared_to_itself() {
//given
diff --git a/src/test/java/org/mockito/internal/util/PrimitivesTest.java b/src/test/java/org/mockito/internal/util/PrimitivesTest.java
index 2896bd4..34dd362 100644
--- a/src/test/java/org/mockito/internal/util/PrimitivesTest.java
+++ b/src/test/java/org/mockito/internal/util/PrimitivesTest.java
@@ -69,21 +69,21 @@
@Test
public void should_check_that_value_type_is_assignable_to_wrapper_reference() {
- assertThat(Primitives.isAssignableFromWrapper(int.class, Integer.class));
- assertThat(Primitives.isAssignableFromWrapper(Integer.class, Integer.class));
- assertThat(Primitives.isAssignableFromWrapper(long.class, Long.class));
- assertThat(Primitives.isAssignableFromWrapper(Long.class, Long.class));
- assertThat(Primitives.isAssignableFromWrapper(double.class, Double.class));
- assertThat(Primitives.isAssignableFromWrapper(Double.class, Double.class));
- assertThat(Primitives.isAssignableFromWrapper(float.class, Float.class));
- assertThat(Primitives.isAssignableFromWrapper(Float.class, Float.class));
- assertThat(Primitives.isAssignableFromWrapper(char.class, Character.class));
- assertThat(Primitives.isAssignableFromWrapper(Character.class, Character.class));
- assertThat(Primitives.isAssignableFromWrapper(short.class, Short.class));
- assertThat(Primitives.isAssignableFromWrapper(Short.class, Short.class));
- assertThat(Primitives.isAssignableFromWrapper(byte.class, Byte.class));
- assertThat(Primitives.isAssignableFromWrapper(Byte.class, Byte.class));
- assertThat(Primitives.isAssignableFromWrapper(boolean.class, Boolean.class));
- assertThat(Primitives.isAssignableFromWrapper(Boolean.class, Boolean.class));
+ assertThat(Primitives.isAssignableFromWrapper(int.class, Integer.class)).isTrue();
+ assertThat(Primitives.isAssignableFromWrapper(Integer.class, Integer.class)).isTrue();
+ assertThat(Primitives.isAssignableFromWrapper(long.class, Long.class)).isTrue();
+ assertThat(Primitives.isAssignableFromWrapper(Long.class, Long.class)).isTrue();
+ assertThat(Primitives.isAssignableFromWrapper(double.class, Double.class)).isTrue();
+ assertThat(Primitives.isAssignableFromWrapper(Double.class, Double.class)).isTrue();
+ assertThat(Primitives.isAssignableFromWrapper(float.class, Float.class)).isTrue();
+ assertThat(Primitives.isAssignableFromWrapper(Float.class, Float.class)).isTrue();
+ assertThat(Primitives.isAssignableFromWrapper(char.class, Character.class)).isTrue();
+ assertThat(Primitives.isAssignableFromWrapper(Character.class, Character.class)).isTrue();
+ assertThat(Primitives.isAssignableFromWrapper(short.class, Short.class)).isTrue();
+ assertThat(Primitives.isAssignableFromWrapper(Short.class, Short.class)).isTrue();
+ assertThat(Primitives.isAssignableFromWrapper(byte.class, Byte.class)).isTrue();
+ assertThat(Primitives.isAssignableFromWrapper(Byte.class, Byte.class)).isTrue();
+ assertThat(Primitives.isAssignableFromWrapper(boolean.class, Boolean.class)).isTrue();
+ assertThat(Primitives.isAssignableFromWrapper(Boolean.class, Boolean.class)).isTrue();
}
}
diff --git a/src/test/java/org/mockito/internal/verification/checkers/NumberOfInvocationsCheckerTest.java b/src/test/java/org/mockito/internal/verification/checkers/NumberOfInvocationsCheckerTest.java
index af9d3cb..61b2f2e 100644
--- a/src/test/java/org/mockito/internal/verification/checkers/NumberOfInvocationsCheckerTest.java
+++ b/src/test/java/org/mockito/internal/verification/checkers/NumberOfInvocationsCheckerTest.java
@@ -5,10 +5,6 @@
package org.mockito.internal.verification.checkers;
-import static java.util.Arrays.asList;
-import static java.util.Collections.emptyList;
-import static org.assertj.core.api.Assertions.assertThat;
-
import java.util.List;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
@@ -28,6 +24,10 @@
import org.mockito.junit.MockitoJUnitRunner;
import org.mockitousage.IMethods;
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
+import static org.assertj.core.api.Assertions.assertThat;
+
@RunWith(MockitoJUnitRunner.class)
public class NumberOfInvocationsCheckerTest {
@@ -58,7 +58,7 @@
}
@Test
- public void shouldReportWithLastInvocationStackTrace() throws Exception {
+ public void shouldReportAllInvocationsStackTrace() throws Exception {
wanted = buildSimpleMethod().toInvocationMatcher();
invocations = asList(buildSimpleMethod().toInvocation(), buildSimpleMethod().toInvocation());
@@ -66,7 +66,7 @@
exception.expectMessage("mock.simpleMethod()");
exception.expectMessage("Wanted 100 times");
exception.expectMessage("But was 2 times");
- exception.expectMessage(containsTimes("-> at", 2));
+ exception.expectMessage(containsTimes("-> at", 3));
NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 100);
}
@@ -86,7 +86,7 @@
}
@Test
- public void shouldReportWithFirstUndesiredInvocationStackTrace() throws Exception {
+ public void shouldReportWithAllInvocationsStackTrace() throws Exception {
Invocation first = buildSimpleMethod().toInvocation();
Invocation second = buildSimpleMethod().toInvocation();
Invocation third = buildSimpleMethod().toInvocation();
@@ -95,6 +95,8 @@
wanted = buildSimpleMethod().toInvocationMatcher();
exception.expect(TooManyActualInvocations.class);
+ exception.expectMessage("" + first.getLocation());
+ exception.expectMessage("" + second.getLocation());
exception.expectMessage("" + third.getLocation());
NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 2);
}
diff --git a/src/test/java/org/mockito/internal/verification/checkers/NumberOfInvocationsInOrderCheckerTest.java b/src/test/java/org/mockito/internal/verification/checkers/NumberOfInvocationsInOrderCheckerTest.java
index 2e72033..bc031ac 100644
--- a/src/test/java/org/mockito/internal/verification/checkers/NumberOfInvocationsInOrderCheckerTest.java
+++ b/src/test/java/org/mockito/internal/verification/checkers/NumberOfInvocationsInOrderCheckerTest.java
@@ -5,11 +5,6 @@
package org.mockito.internal.verification.checkers;
-import static java.util.Arrays.asList;
-import static java.util.Collections.emptyList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-
import java.util.List;
import org.hamcrest.BaseMatcher;
@@ -27,6 +22,11 @@
import org.mockito.invocation.Invocation;
import org.mockitousage.IMethods;
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
public class NumberOfInvocationsInOrderCheckerTest {
private InvocationMatcher wanted;
@@ -102,7 +102,7 @@
}
@Test
- public void shouldReportWithLastInvocationStackTrace() throws Exception {
+ public void shouldReportWithAllInvocationsStackTrace() throws Exception {
wanted = buildSimpleMethod().toInvocationMatcher();
invocations = asList(buildSimpleMethod().toInvocation(), buildSimpleMethod().toInvocation());
@@ -110,7 +110,7 @@
exception.expectMessage("mock.simpleMethod()");
exception.expectMessage("Wanted 100 times");
exception.expectMessage("But was 2 times");
- exception.expectMessage(containsTimes("-> at", 2));
+ exception.expectMessage(containsTimes("-> at", 3));
NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 100, context);
@@ -168,7 +168,7 @@
exception.expect(VerificationInOrderFailure.class);
exception.expectMessage("mock.simpleMethod()");
exception.expectMessage("Wanted 0 times");
- exception.expectMessage("But was 1 time. Undesired invocation");
+ exception.expectMessage("But was 1 time:");
exception.expectMessage("" + first.getLocation());
NumberOfInvocationsChecker.checkNumberOfInvocations(invocations, wanted, 0, context);
diff --git a/src/test/java/org/mockitousage/basicapi/MocksCreationTest.java b/src/test/java/org/mockitousage/basicapi/MocksCreationTest.java
index 5d2af03..98ab7d2 100644
--- a/src/test/java/org/mockitousage/basicapi/MocksCreationTest.java
+++ b/src/test/java/org/mockitousage/basicapi/MocksCreationTest.java
@@ -90,6 +90,7 @@
} catch (MockitoException e) {}
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test
public void shouldAllowCreatingSpiesWithCorrectType() {
List list = new LinkedList();
diff --git a/src/test/java/org/mockitousage/basicapi/MocksSerializationForAnnotationTest.java b/src/test/java/org/mockitousage/basicapi/MocksSerializationForAnnotationTest.java
index 5231a1b..31cdd04 100644
--- a/src/test/java/org/mockitousage/basicapi/MocksSerializationForAnnotationTest.java
+++ b/src/test/java/org/mockitousage/basicapi/MocksSerializationForAnnotationTest.java
@@ -19,7 +19,6 @@
import java.io.ByteArrayOutputStream;
import java.io.Serializable;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Observable;
@@ -254,19 +253,19 @@
@Test
public void should_serialize_with_real_object_spy() throws Exception {
// given
- List<Object> list = new ArrayList<Object>();
- List<Object> spy = mock(ArrayList.class, withSettings()
+ SerializableSample list = new SerializableSample();
+ SerializableSample spy = mock(SerializableSample.class, withSettings()
.spiedInstance(list)
.defaultAnswer(CALLS_REAL_METHODS)
.serializable());
- when(spy.size()).thenReturn(100);
+ when(spy.foo()).thenReturn("foo");
// when
ByteArrayOutputStream serialized = serializeMock(spy);
// then
- List<?> readObject = deserializeMock(serialized, List.class);
- assertEquals(100, readObject.size());
+ SerializableSample readObject = deserializeMock(serialized, SerializableSample.class);
+ assertEquals("foo", readObject.foo());
}
@Test
@@ -313,14 +312,10 @@
.isInstanceOf(IMethods.class);
}
-
-
static class NotSerializableAndNoDefaultConstructor {
NotSerializableAndNoDefaultConstructor(Observable o) { super(); }
}
-
-
static class SerializableAndNoDefaultConstructor implements Serializable {
SerializableAndNoDefaultConstructor(Observable o) { super(); }
}
@@ -337,4 +332,11 @@
serializeAndBack(testClass.serializableAndNoDefaultConstructor);
}
+
+ public static class SerializableSample implements Serializable {
+
+ public String foo() {
+ return null;
+ }
+ }
}
diff --git a/src/test/java/org/mockitousage/basicapi/MocksSerializationTest.java b/src/test/java/org/mockitousage/basicapi/MocksSerializationTest.java
index 6445aa0..02bcc3d 100644
--- a/src/test/java/org/mockitousage/basicapi/MocksSerializationTest.java
+++ b/src/test/java/org/mockitousage/basicapi/MocksSerializationTest.java
@@ -5,6 +5,7 @@
package org.mockitousage.basicapi;
+import net.bytebuddy.ClassFileVersion;
import org.assertj.core.api.Assertions;
import org.junit.Test;
import org.mockito.InOrder;
@@ -20,13 +21,12 @@
import java.io.ByteArrayOutputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Observable;
import static org.junit.Assert.*;
-import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
import static org.mockito.Mockito.*;
import static org.mockitoutil.SimpleSerializationUtil.*;
@@ -275,19 +275,19 @@
@Test
public void should_serialize_with_real_object_spy() throws Exception {
// given
- List<Object> list = new ArrayList<Object>();
- List<Object> spy = mock(ArrayList.class, withSettings()
- .spiedInstance(list)
+ SerializableClass sample = new SerializableClass();
+ SerializableClass spy = mock(SerializableClass.class, withSettings()
+ .spiedInstance(sample)
.defaultAnswer(CALLS_REAL_METHODS)
.serializable());
- when(spy.size()).thenReturn(100);
+ when(spy.foo()).thenReturn("foo");
// when
ByteArrayOutputStream serialized = serializeMock(spy);
// then
- List<?> readObject = deserializeMock(serialized, List.class);
- assertEquals(100, readObject.size());
+ SerializableClass readObject = deserializeMock(serialized, SerializableClass.class);
+ assertEquals("foo", readObject.foo());
}
@Test
@@ -346,8 +346,6 @@
.isInstanceOf(IMethods.class);
}
-
-
static class SerializableAndNoDefaultConstructor implements Serializable {
SerializableAndNoDefaultConstructor(Observable o) { super(); }
}
@@ -385,7 +383,7 @@
@Test
public void BUG_ISSUE_399_try_some_mocks_with_current_answers() throws Exception {
- assumeFalse(System.getProperty("java.version").startsWith("1.6")); // Bug in last public HotSpot 1.6
+ assumeTrue(ClassFileVersion.ofThisVm().isAtLeast(ClassFileVersion.JAVA_V7));
IMethods iMethods = mock(IMethods.class, withSettings().serializable().defaultAnswer(RETURNS_DEEP_STUBS));
@@ -393,4 +391,11 @@
serializeAndBack(iMethods);
}
+
+ public static class SerializableClass implements Serializable {
+
+ public String foo() {
+ return null;
+ }
+ }
}
diff --git a/src/test/java/org/mockitousage/basicapi/ResetTest.java b/src/test/java/org/mockitousage/basicapi/ResetTest.java
index 150945f..ef199a5 100644
--- a/src/test/java/org/mockitousage/basicapi/ResetTest.java
+++ b/src/test/java/org/mockitousage/basicapi/ResetTest.java
@@ -26,7 +26,6 @@
@Test
public void shouldResetOngoingStubbingSoThatMoreMeaningfulExceptionsAreRaised() {
- mock(IMethods.class);
mock.booleanReturningMethod();
reset(mock);
try {
@@ -95,6 +94,7 @@
verifyNoMoreInteractions(mock, mockTwo);
}
+ @SuppressWarnings({"MockitoUsage", "CheckReturnValue"})
@Test
public void shouldValidateStateWhenResetting() {
//invalid verify:
diff --git a/src/test/java/org/mockitousage/bugs/ActualInvocationHasNullArgumentNPEBugTest.java b/src/test/java/org/mockitousage/bugs/ActualInvocationHasNullArgumentNPEBugTest.java
index b4f38bf..632c8c9 100644
--- a/src/test/java/org/mockitousage/bugs/ActualInvocationHasNullArgumentNPEBugTest.java
+++ b/src/test/java/org/mockitousage/bugs/ActualInvocationHasNullArgumentNPEBugTest.java
@@ -29,9 +29,10 @@
//then
try {
verify(mockFun).doFun("hello");
- fail();
} catch(AssertionError r) {
//it's ok, we just want to reproduce the bug
+ return;
}
+ fail();
}
}
diff --git a/src/test/java/org/mockitousage/bugs/FillInStackTraceScenariosTest.java b/src/test/java/org/mockitousage/bugs/FillInStackTraceScenariosTest.java
new file mode 100644
index 0000000..5e3193e
--- /dev/null
+++ b/src/test/java/org/mockitousage/bugs/FillInStackTraceScenariosTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
+package org.mockitousage.bugs;
+
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockitousage.IMethods;
+import org.mockitoutil.TestBase;
+
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.when;
+
+/**
+ * These tests check that ThrowsException#answer throws an instance returned
+ * by Throwable#fillInStackTrace of the provided throwable.
+ *
+ * <p>A well-behaved Throwable implementation must always return a reference to this
+ * from #fillInStackTrace according to the method contract.
+ * However, Mockito throws the exception returned from #fillInStackTrace for backwards compatibility
+ * (or the provided exception if the method returns null).
+ *
+ * @see Throwable#fillInStackTrace()
+ * @see <a href="https://github.com/mockito/mockito/issues/866">#866</a>
+ */
+public class FillInStackTraceScenariosTest extends TestBase {
+
+ @Mock IMethods mock;
+
+ private class SomeException extends RuntimeException {}
+
+ class NullStackTraceException extends RuntimeException {
+ public Exception fillInStackTrace() {
+ return null;
+ }
+ }
+
+ class NewStackTraceException extends RuntimeException {
+ public Exception fillInStackTrace() {
+ return new SomeException();
+ }
+ }
+
+ //issue 866
+ @Test
+ public void avoids_NPE() {
+ when(mock.simpleMethod()).thenThrow(new NullStackTraceException());
+ try {
+ mock.simpleMethod();
+ fail();
+ } catch(NullStackTraceException e) {}
+ }
+
+ @Test
+ public void uses_return_value_from_fillInStackTrace() {
+ when(mock.simpleMethod()).thenThrow(new NewStackTraceException());
+ try {
+ mock.simpleMethod();
+ fail();
+ } catch(SomeException e) {}
+ }
+}
diff --git a/src/test/java/org/mockitousage/bugs/NPEWhenCustomExceptionStackTraceReturnNullTest.java b/src/test/java/org/mockitousage/bugs/NPEWhenCustomExceptionStackTraceReturnNullTest.java
deleted file mode 100644
index 92a1305..0000000
--- a/src/test/java/org/mockitousage/bugs/NPEWhenCustomExceptionStackTraceReturnNullTest.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2017 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
-package org.mockitousage.bugs;
-
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockitousage.IMethods;
-import org.mockitoutil.TestBase;
-
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.when;
-
-public class NPEWhenCustomExceptionStackTraceReturnNullTest extends TestBase {
-
- @Mock
- IMethods mock;
-
- class NullStackTraceException extends RuntimeException {
- @Override
- public Exception fillInStackTrace() {
- return null;
- }
- }
-
- //issue 866
- @Test
- public void shouldNotThrowNPE() {
- when(mock.simpleMethod()).thenThrow(new NullStackTraceException());
- try {
- mock.simpleMethod();
- fail();
- } catch(NullStackTraceException e) {}
- }
-}
diff --git a/src/test/java/org/mockitousage/bugs/varargs/VarargsNotPlayingWithAnyObjectTest.java b/src/test/java/org/mockitousage/bugs/varargs/VarargsNotPlayingWithAnyObjectTest.java
index 9a96741..2b0cbff 100644
--- a/src/test/java/org/mockitousage/bugs/varargs/VarargsNotPlayingWithAnyObjectTest.java
+++ b/src/test/java/org/mockitousage/bugs/varargs/VarargsNotPlayingWithAnyObjectTest.java
@@ -10,8 +10,13 @@
import org.mockitoutil.TestBase;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.anyObject;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.anyVararg;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
//see issue 62
public class VarargsNotPlayingWithAnyObjectTest extends TestBase {
@@ -35,16 +40,10 @@
verify(mock, never()).run(anyString(), eq("f"));
}
- //we cannot use anyObject() for entire varargs because it makes the verification pick up extra invocations
- //see other tests in this package
@Test
- public void shouldNotAllowUsingAnyObjectForVarArgs() {
+ public void shouldAllowUsingAnyObjectForVarArgs() {
mock.run("a", "b");
-
- try {
- verify(mock).run((String[]) anyObject());
- fail();
- } catch (AssertionError e) {}
+ verify(mock).run((String[]) anyObject());
}
@Test
diff --git a/src/test/java/org/mockitousage/constructor/CreatingMocksWithConstructorTest.java b/src/test/java/org/mockitousage/constructor/CreatingMocksWithConstructorTest.java
index 8b0332d..fe626b0 100644
--- a/src/test/java/org/mockitousage/constructor/CreatingMocksWithConstructorTest.java
+++ b/src/test/java/org/mockitousage/constructor/CreatingMocksWithConstructorTest.java
@@ -248,6 +248,7 @@
}
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test
public void mocking_interfaces_with_constructor() {
//at the moment this is allowed however we can be more strict if needed
diff --git a/src/test/java/org/mockitousage/junitrule/StrictJUnitRuleTest.java b/src/test/java/org/mockitousage/junitrule/StrictJUnitRuleTest.java
index f4e3e95..b802013 100644
--- a/src/test/java/org/mockitousage/junitrule/StrictJUnitRuleTest.java
+++ b/src/test/java/org/mockitousage/junitrule/StrictJUnitRuleTest.java
@@ -157,6 +157,7 @@
mock2.booleanObjectReturningMethod();
}
+ @SuppressWarnings({"MockitoUsage", "CheckReturnValue"})
@Test public void rule_validates_mockito_usage() throws Throwable {
//expect
rule.expectFailure(UnfinishedVerificationException.class);
diff --git a/src/test/java/org/mockitousage/junitrunner/SilentRunnerTest.java b/src/test/java/org/mockitousage/junitrunner/SilentRunnerTest.java
index 284b197..f22d7ac 100644
--- a/src/test/java/org/mockitousage/junitrunner/SilentRunnerTest.java
+++ b/src/test/java/org/mockitousage/junitrunner/SilentRunnerTest.java
@@ -104,6 +104,8 @@
@RunWith(MockitoJUnitRunner.Silent.class)
public static class UsesFrameworkIncorrectly {
@Mock List<?> list;
+
+ @SuppressWarnings({"MockitoUsage", "CheckReturnValue"})
@Test public void unfinished_stubbing_test_method() {
when(list.get(0)); //unfinished stubbing
}
diff --git a/src/test/java/org/mockitousage/junitrunner/StubbingWarningsJUnitRunnerTest.java b/src/test/java/org/mockitousage/junitrunner/StubbingWarningsJUnitRunnerTest.java
index bc7fd2b..7d8d537 100644
--- a/src/test/java/org/mockitousage/junitrunner/StubbingWarningsJUnitRunnerTest.java
+++ b/src/test/java/org/mockitousage/junitrunner/StubbingWarningsJUnitRunnerTest.java
@@ -119,6 +119,7 @@
@RunWith(TestableJUnitRunner.class)
public static class InvalidMockitoUsage {
@Mock IMethods mock;
+ @SuppressWarnings({"MockitoUsage", "CheckReturnValue"})
@Test public void test() throws Exception {
when(mock.simpleMethod()); // <-- unfinished stubbing
}
diff --git a/src/test/java/org/mockitousage/matchers/MoreMatchersTest.java b/src/test/java/org/mockitousage/matchers/MoreMatchersTest.java
index ad27b48..46773b8 100644
--- a/src/test/java/org/mockitousage/matchers/MoreMatchersTest.java
+++ b/src/test/java/org/mockitousage/matchers/MoreMatchersTest.java
@@ -5,15 +5,16 @@
package org.mockitousage.matchers;
+import org.assertj.core.api.ThrowableAssert;
import org.junit.Test;
import org.mockito.Mock;
+import org.mockito.exceptions.verification.junit.ArgumentsAreDifferent;
import org.mockitousage.IMethods;
import org.mockitoutil.TestBase;
import java.util.*;
-
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -44,16 +45,21 @@
verify(mock).simpleMethod(isA(List.class));
verify(mock).simpleMethod(any(List.class));
-
mock.simpleMethod((String) null);
- try {
- verify(mock).simpleMethod(isA(String.class));
- fail();
- } catch (AssertionError ignored) { }
- try {
- verify(mock).simpleMethod(any(String.class));
- fail();
- } catch (AssertionError ignored) { }
+
+ assertThatThrownBy(new ThrowableAssert.ThrowingCallable() {
+ @Override
+ public void call() {
+ verify(mock).simpleMethod(isA(String.class));
+ }
+ }).isInstanceOf(ArgumentsAreDifferent.class);
+
+ assertThatThrownBy(new ThrowableAssert.ThrowingCallable() {
+ @Override
+ public void call() {
+ verify(mock).simpleMethod(any(String.class));
+ }
+ }).isInstanceOf(ArgumentsAreDifferent.class);
}
@Test
diff --git a/src/test/java/org/mockitousage/misuse/DescriptiveMessagesOnMisuseTest.java b/src/test/java/org/mockitousage/misuse/DescriptiveMessagesOnMisuseTest.java
index 09f0034..41e4a16 100644
--- a/src/test/java/org/mockitousage/misuse/DescriptiveMessagesOnMisuseTest.java
+++ b/src/test/java/org/mockitousage/misuse/DescriptiveMessagesOnMisuseTest.java
@@ -61,6 +61,7 @@
// when(mock.differentMethod()).thenReturn("");
}
+ @SuppressWarnings({"MockitoUsage", "CheckReturnValue"})
@Test(expected=NotAMockException.class)
public void shouldScreamWhenWholeMethodPassedToVerify() {
verify(mock.booleanReturningMethod());
@@ -71,16 +72,19 @@
verifyNoMoreInteractions(mock.byteReturningMethod());
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test(expected=NotAMockException.class)
public void shouldScreamWhenInOrderCreatedWithDodgyMock() {
inOrder("not a mock");
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test(expected=NullInsteadOfMockException.class)
public void shouldScreamWhenInOrderCreatedWithNulls() {
inOrder(mock, null);
}
+ @SuppressWarnings({"MockitoUsage", "CheckReturnValue"})
@Test(expected=NullInsteadOfMockException.class)
public void shouldScreamNullPassedToVerify() {
verify(null);
diff --git a/src/test/java/org/mockitousage/misuse/DetectingMisusedMatchersTest.java b/src/test/java/org/mockitousage/misuse/DetectingMisusedMatchersTest.java
index 7bf1896..267e93c 100644
--- a/src/test/java/org/mockitousage/misuse/DetectingMisusedMatchersTest.java
+++ b/src/test/java/org/mockitousage/misuse/DetectingMisusedMatchersTest.java
@@ -83,6 +83,7 @@
}
+ @SuppressWarnings({"MockitoUsage", "CheckReturnValue"})
@Test
public void shouldSayUnfinishedVerificationButNotInvalidUseOfMatchers() {
assumeTrue("Does not apply for inline mocks", withFinal.getClass() != WithFinal.class);
diff --git a/src/test/java/org/mockitousage/misuse/ExplicitFrameworkValidationTest.java b/src/test/java/org/mockitousage/misuse/ExplicitFrameworkValidationTest.java
index 0fcb41c..9ebc690 100644
--- a/src/test/java/org/mockitousage/misuse/ExplicitFrameworkValidationTest.java
+++ b/src/test/java/org/mockitousage/misuse/ExplicitFrameworkValidationTest.java
@@ -23,6 +23,7 @@
@Mock IMethods mock;
+ @SuppressWarnings({"MockitoUsage", "CheckReturnValue"})
@Test
public void shouldValidateExplicitly() {
verify(mock);
@@ -32,6 +33,7 @@
} catch (UnfinishedVerificationException e) {}
}
+ @SuppressWarnings({"MockitoUsage", "CheckReturnValue"})
@Test
public void shouldDetectUnfinishedStubbing() {
when(mock.simpleMethod());
diff --git a/src/test/java/org/mockitousage/misuse/InvalidUsageTest.java b/src/test/java/org/mockitousage/misuse/InvalidUsageTest.java
index ff3ca09..2197300 100644
--- a/src/test/java/org/mockitousage/misuse/InvalidUsageTest.java
+++ b/src/test/java/org/mockitousage/misuse/InvalidUsageTest.java
@@ -37,6 +37,7 @@
verifyZeroInteractions();
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test(expected=MockitoException.class)
public void shouldNotCreateInOrderObjectWithoutMocks() {
inOrder();
@@ -82,6 +83,7 @@
assumeFalse("Inlining mock allows mocking final classes", mock(FinalClass.class).getClass() == FinalClass.class);
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test(expected=MockitoException.class)
public void shouldNotAllowMockingPrimitives() throws Exception {
mock(Integer.TYPE);
@@ -104,6 +106,7 @@
verifyZeroInteractions(inter);
}
+ @Test
public void shouldNotMockObjectMethodsOnClass() throws Exception {
Object clazz = mock(ObjectLikeInterface.class);
diff --git a/src/test/java/org/mockitousage/packageprotected/MockingPackageProtectedTest.java b/src/test/java/org/mockitousage/packageprotected/MockingPackageProtectedTest.java
index b06d073..b740508 100644
--- a/src/test/java/org/mockitousage/packageprotected/MockingPackageProtectedTest.java
+++ b/src/test/java/org/mockitousage/packageprotected/MockingPackageProtectedTest.java
@@ -16,6 +16,7 @@
class Bar {}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test
public void shouldMockPackageProtectedClasses() {
mock(PackageProtected.class);
diff --git a/src/test/java/org/mockitousage/serialization/DeepStubsSerializableTest.java b/src/test/java/org/mockitousage/serialization/DeepStubsSerializableTest.java
index 1f12cdf..3294614 100644
--- a/src/test/java/org/mockitousage/serialization/DeepStubsSerializableTest.java
+++ b/src/test/java/org/mockitousage/serialization/DeepStubsSerializableTest.java
@@ -59,31 +59,56 @@
// then revert to the default RETURNS_DEEP_STUBS and the code will raise a ClassCastException
}
-
static class SampleClass implements Serializable {
- SampleClass2 getSample() { return new SampleClass2(); }
+
+ SampleClass2 getSample() {
+ return new SampleClass2();
+ }
}
static class SampleClass2 implements Serializable {
- boolean isFalse() { return false; }
- int number() { return 100; }
+
+ boolean isFalse() {
+ return false;
+ }
+
+ int number() {
+ return 100;
+ }
}
static class Container<E> implements Iterable<E>, Serializable {
+
private E e;
- public Container(E e) { this.e = e; }
- public E get() { return e; }
+
+ public Container(E e) {
+ this.e = e;
+ }
+
+ public E get() {
+ return e;
+ }
public Iterator<E> iterator() {
return new Iterator<E>() {
- public boolean hasNext() { return true; }
- public E next() { return e; }
- public void remove() { }
+ public boolean hasNext() {
+ return true;
+ }
+
+ public E next() {
+ return e;
+ }
+
+ public void remove() {
+ }
};
}
}
static class ListContainer extends Container<List<String>> {
- public ListContainer(List<String> list) { super(list); }
+
+ public ListContainer(List<String> list) {
+ super(list);
+ }
}
}
diff --git a/src/test/java/org/mockitousage/session/MockitoSessionTest.java b/src/test/java/org/mockitousage/session/MockitoSessionTest.java
index 960d888..a87928c 100644
--- a/src/test/java/org/mockitousage/session/MockitoSessionTest.java
+++ b/src/test/java/org/mockitousage/session/MockitoSessionTest.java
@@ -151,6 +151,7 @@
mockito.finishMocking();
}
+ @SuppressWarnings({"MockitoUsage", "CheckReturnValue"})
@Test public void unfinished_stubbing() {
when(mock.simpleMethod());
}
@@ -165,6 +166,7 @@
mockito.finishMocking();
}
+ @SuppressWarnings({"MockitoUsage", "CheckReturnValue"})
@Test public void unfinished_stubbing_with_other_failure() {
when(mock.simpleMethod());
assertTrue(false);
@@ -214,6 +216,7 @@
mockito.finishMocking(new RuntimeException("Boo!"));
}
+ @SuppressWarnings({"MockitoUsage", "CheckReturnValue"})
@Test public void invalid_mockito_usage() {
verify(mock);
}
diff --git a/src/test/java/org/mockitousage/spies/SpyingOnRealObjectsTest.java b/src/test/java/org/mockitousage/spies/SpyingOnRealObjectsTest.java
index f67c623..8603ca0 100644
--- a/src/test/java/org/mockitousage/spies/SpyingOnRealObjectsTest.java
+++ b/src/test/java/org/mockitousage/spies/SpyingOnRealObjectsTest.java
@@ -40,6 +40,7 @@
verify(spy).add("two");
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test
public void shouldBeAbleToMockObjectBecauseWhyNot() {
spy(new Object());
diff --git a/src/test/java/org/mockitousage/stacktrace/ClickableStackTracesWhenFrameworkMisusedTest.java b/src/test/java/org/mockitousage/stacktrace/ClickableStackTracesWhenFrameworkMisusedTest.java
index bdefa14..e9a98c1 100644
--- a/src/test/java/org/mockitousage/stacktrace/ClickableStackTracesWhenFrameworkMisusedTest.java
+++ b/src/test/java/org/mockitousage/stacktrace/ClickableStackTracesWhenFrameworkMisusedTest.java
@@ -44,6 +44,7 @@
}
}
+ @SuppressWarnings({"MockitoUsage", "CheckReturnValue"})
private void unfinishedStubbingHere() {
when(mock.simpleMethod());
}
@@ -73,6 +74,7 @@
}
}
+ @SuppressWarnings({"MockitoUsage", "CheckReturnValue"})
private void unfinishedVerificationHere() {
verify(mock);
}
diff --git a/src/test/java/org/mockitousage/stacktrace/ModellingDescriptiveMessagesTest.java b/src/test/java/org/mockitousage/stacktrace/ModellingDescriptiveMessagesTest.java
index a09ee71..e1bd9af 100644
--- a/src/test/java/org/mockitousage/stacktrace/ModellingDescriptiveMessagesTest.java
+++ b/src/test/java/org/mockitousage/stacktrace/ModellingDescriptiveMessagesTest.java
@@ -32,6 +32,7 @@
super.makeStackTracesClean();
}
+ @SuppressWarnings({"MockitoUsage", "CheckReturnValue"})
@Test
public void makeSureStateIsValidatedInTheVeryFirstTestThanksToTheRunner() {
//mess up the state:
@@ -137,6 +138,7 @@
m.simpleMethod();
}
+ @SuppressWarnings({"MockitoUsage", "CheckReturnValue"})
@Test
public void shouldPointOutUnfinishedStubbing() {
when(mock.simpleMethod());
@@ -167,26 +169,31 @@
argument.getValue();
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test
public void shouldScreamWhenNullPassedInsteadOfAnInterface() {
mock(IMethods.class, withSettings().extraInterfaces(List.class, null));
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test
public void shouldScreamWhenNonInterfacePassed() {
mock(IMethods.class, withSettings().extraInterfaces(LinkedList.class));
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test
public void shouldScreamWhenExtraIsTheSame() {
mock(IMethods.class, withSettings().extraInterfaces(IMethods.class));
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test
public void shouldScreamWhenExtraInterfacesEmpty() {
mock(IMethods.class, withSettings().extraInterfaces());
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test
public void shouldScreamWhenExtraInterfacesIsANullArray() {
mock(IMethods.class, withSettings().extraInterfaces((Class<?>[]) null));
diff --git a/src/test/java/org/mockitousage/stacktrace/StackTraceFilteringTest.java b/src/test/java/org/mockitousage/stacktrace/StackTraceFilteringTest.java
index 23f6033..6186130 100644
--- a/src/test/java/org/mockitousage/stacktrace/StackTraceFilteringTest.java
+++ b/src/test/java/org/mockitousage/stacktrace/StackTraceFilteringTest.java
@@ -72,6 +72,7 @@
}
}
+ @SuppressWarnings({"MockitoUsage", "CheckReturnValue"})
@Test
public void shouldFilterStacktraceOnMockitoException() {
verify(mock);
diff --git a/src/test/java/org/mockitousage/stubbing/BasicStubbingTest.java b/src/test/java/org/mockitousage/stubbing/BasicStubbingTest.java
index 4dd9d8f..9401320 100644
--- a/src/test/java/org/mockitousage/stubbing/BasicStubbingTest.java
+++ b/src/test/java/org/mockitousage/stubbing/BasicStubbingTest.java
@@ -93,6 +93,7 @@
}
}
+ @SuppressWarnings({"CheckReturnValue", "MockitoUsage"})
@Test
public void should_allow_mocking_when_to_string_is_final() throws Exception {
mock(Foo.class);
diff --git a/src/test/java/org/mockitousage/stubbing/StubbingConsecutiveAnswersTest.java b/src/test/java/org/mockitousage/stubbing/StubbingConsecutiveAnswersTest.java
index f8fa2b5..47c2172 100644
--- a/src/test/java/org/mockitousage/stubbing/StubbingConsecutiveAnswersTest.java
+++ b/src/test/java/org/mockitousage/stubbing/StubbingConsecutiveAnswersTest.java
@@ -42,6 +42,34 @@
}
@Test
+ public void should_return_consecutive_values_first_var_arg_null() throws Exception {
+ when(mock.simpleMethod()).thenReturn("one", (String) null);
+
+ assertEquals("one", mock.simpleMethod());
+ assertNull(mock.simpleMethod());
+ assertNull(mock.simpleMethod());
+ }
+
+ @Test
+ public void should_return_consecutive_values_var_arg_null() throws Exception {
+ when(mock.simpleMethod()).thenReturn("one", (String[]) null);
+
+ assertEquals("one", mock.simpleMethod());
+ assertNull(mock.simpleMethod());
+ assertNull(mock.simpleMethod());
+ }
+
+ @Test
+ public void should_return_consecutive_values_var_args_contain_null() throws Exception {
+ when(mock.simpleMethod()).thenReturn("one", "two", null);
+
+ assertEquals("one", mock.simpleMethod());
+ assertEquals("two", mock.simpleMethod());
+ assertNull(mock.simpleMethod());
+ assertNull(mock.simpleMethod());
+ }
+
+ @Test
public void should_return_consecutive_values_set_by_shorten_then_return_method() throws Exception {
when(mock.simpleMethod()).thenReturn("one", "two", "three");
diff --git a/src/test/java/org/mockitousage/stubbing/StubbingWarningsTest.java b/src/test/java/org/mockitousage/stubbing/StubbingWarningsTest.java
index 754b7dc..6bf2041 100644
--- a/src/test/java/org/mockitousage/stubbing/StubbingWarningsTest.java
+++ b/src/test/java/org/mockitousage/stubbing/StubbingWarningsTest.java
@@ -96,6 +96,7 @@
filterLineNo(logger.getLoggedInfo()));
}
+ @SuppressWarnings({"MockitoUsage", "CheckReturnValue"})
@Test(expected = MockitoException.class) public void unfinished_verification_without_throwable() throws Throwable {
//when
verify(mock);
@@ -103,6 +104,7 @@
mockito.finishMocking();
}
+ @SuppressWarnings({"MockitoUsage", "CheckReturnValue"})
@Test public void unfinished_verification_with_throwable() throws Throwable {
//when
verify(mock);
diff --git a/src/test/java/org/mockitousage/stubbing/StubbingWithDelegateTest.java b/src/test/java/org/mockitousage/stubbing/StubbingWithDelegateTest.java
index 885e78e..24c4854 100644
--- a/src/test/java/org/mockitousage/stubbing/StubbingWithDelegateTest.java
+++ b/src/test/java/org/mockitousage/stubbing/StubbingWithDelegateTest.java
@@ -111,7 +111,7 @@
List<String> mock = mock(List.class, delegatesTo(new FakeList<String>()));
mock.set(1, "1");
- assertThat(mock.get(1).equals("1"));
+ assertThat(mock.get(1).equals("1")).isTrue();
}
@Test
@@ -119,7 +119,7 @@
List<String> mock = mock(List.class, delegatesTo(new FakeList<String>()));
List<String> subList = mock.subList(0, 0);
- assertThat(subList.isEmpty());
+ assertThat(subList.isEmpty()).isTrue();
}
@Test
diff --git a/src/test/java/org/mockitousage/stubbing/StubbingWithThrowablesTest.java b/src/test/java/org/mockitousage/stubbing/StubbingWithThrowablesTest.java
index 9f526bf..9353724 100644
--- a/src/test/java/org/mockitousage/stubbing/StubbingWithThrowablesTest.java
+++ b/src/test/java/org/mockitousage/stubbing/StubbingWithThrowablesTest.java
@@ -22,6 +22,9 @@
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
+
+import org.assertj.core.api.Assertions;
+import org.assertj.core.api.ThrowableAssert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -49,13 +52,54 @@
}
@Test
+ public void throws_same_exception_consecutively() {
+ when(mock.add("")).thenThrow(new ExceptionOne());
+
+ //1st invocation
+ Assertions.assertThatThrownBy(new ThrowableAssert.ThrowingCallable() {
+ public void call() {
+ mock.add("");
+ }
+ }).isInstanceOf(ExceptionOne.class);
+
+ mock.add("1");
+
+ //2nd invocation
+ Assertions.assertThatThrownBy(new ThrowableAssert.ThrowingCallable() {
+ public void call() {
+ mock.add("");
+ }
+ }).isInstanceOf(ExceptionOne.class);
+ }
+
+ @Test
+ public void throws_same_exception_consecutively_with_doThrow() {
+ doThrow(new ExceptionOne()).when(mock).clear();
+
+ //1st invocation
+ Assertions.assertThatThrownBy(new ThrowableAssert.ThrowingCallable() {
+ public void call() {
+ mock.clear();
+ }
+ }).isInstanceOf(ExceptionOne.class);
+
+ mock.add("1");
+
+ //2nd invocation
+ Assertions.assertThatThrownBy(new ThrowableAssert.ThrowingCallable() {
+ public void call() {
+ mock.clear();
+ }
+ }).isInstanceOf(ExceptionOne.class);
+ }
+
+ @Test
public void shouldStubWithThrowable() throws Exception {
IllegalArgumentException expected = new IllegalArgumentException("thrown by mock");
when(mock.add("throw")).thenThrow(expected);
exception.expect(sameInstance(expected));
mock.add("throw");
-
}
@Test
diff --git a/src/test/java/org/mockitousage/verification/BasicVerificationInOrderTest.java b/src/test/java/org/mockitousage/verification/BasicVerificationInOrderTest.java
index ccf3570..b0e3179 100644
--- a/src/test/java/org/mockitousage/verification/BasicVerificationInOrderTest.java
+++ b/src/test/java/org/mockitousage/verification/BasicVerificationInOrderTest.java
@@ -264,7 +264,7 @@
verifyZeroInteractions(mockOne);
}
- @SuppressWarnings("all")
+ @SuppressWarnings({"all", "CheckReturnValue", "MockitoUsage"})
@Test(expected = MockitoException.class)
public void shouldScreamWhenNullPassed() {
inOrder((Object[])null);
diff --git a/src/test/java/org/mockitousage/verification/BasicVerificationTest.java b/src/test/java/org/mockitousage/verification/BasicVerificationTest.java
index aa350cf..d9a74ff 100644
--- a/src/test/java/org/mockitousage/verification/BasicVerificationTest.java
+++ b/src/test/java/org/mockitousage/verification/BasicVerificationTest.java
@@ -5,16 +5,19 @@
package org.mockitousage.verification;
+import org.assertj.core.api.ThrowableAssert;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.exceptions.verification.NoInteractionsWanted;
import org.mockito.exceptions.verification.TooManyActualInvocations;
import org.mockito.exceptions.verification.WantedButNotInvoked;
+import org.mockito.exceptions.verification.junit.ArgumentsAreDifferent;
import org.mockitousage.IMethods;
import org.mockitoutil.TestBase;
import java.util.List;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.*;
@@ -45,10 +48,13 @@
mock.add("foo");
verify(mock).clear();
- try {
- verify(mock).add("bar");
- fail();
- } catch (AssertionError expected) {}
+
+ assertThatThrownBy(new ThrowableAssert.ThrowingCallable() {
+ @Override
+ public void call() {
+ verify(mock).add("bar");
+ }
+ }).isInstanceOf(ArgumentsAreDifferent.class);
}
@Test
diff --git a/src/test/java/org/mockitousage/verification/DescriptiveMessagesOnVerificationInOrderErrorsTest.java b/src/test/java/org/mockitousage/verification/DescriptiveMessagesOnVerificationInOrderErrorsTest.java
index 4e5f464..8e1bf06 100644
--- a/src/test/java/org/mockitousage/verification/DescriptiveMessagesOnVerificationInOrderErrorsTest.java
+++ b/src/test/java/org/mockitousage/verification/DescriptiveMessagesOnVerificationInOrderErrorsTest.java
@@ -155,7 +155,7 @@
String expectedCause =
"\n" +
- "But was 2 times. Undesired invocation:" +
+ "But was 2 times:" +
"\n" +
"-> at";
assertThat(e).hasMessageContaining(expectedCause);
diff --git a/src/test/java/org/mockitousage/verification/FindingRedundantInvocationsInOrderTest.java b/src/test/java/org/mockitousage/verification/FindingRedundantInvocationsInOrderTest.java
index 0dffbfa..271d95c 100644
--- a/src/test/java/org/mockitousage/verification/FindingRedundantInvocationsInOrderTest.java
+++ b/src/test/java/org/mockitousage/verification/FindingRedundantInvocationsInOrderTest.java
@@ -107,6 +107,7 @@
} catch(VerificationInOrderFailure e) {}
}
+ @SuppressWarnings({"MockitoUsage", "CheckReturnValue"})
@Test
public void shouldValidateState() throws Exception {
//when
diff --git a/subprojects/android/src/main/java/org/mockito/android/internal/creation/AndroidLoadingStrategy.java b/subprojects/android/src/main/java/org/mockito/android/internal/creation/AndroidLoadingStrategy.java
index 600b9bc..5a66ab1 100644
--- a/subprojects/android/src/main/java/org/mockito/android/internal/creation/AndroidLoadingStrategy.java
+++ b/subprojects/android/src/main/java/org/mockito/android/internal/creation/AndroidLoadingStrategy.java
@@ -4,18 +4,19 @@
*/
package org.mockito.android.internal.creation;
-import static org.mockito.internal.util.StringUtil.join;
-
-import java.io.File;
import net.bytebuddy.android.AndroidClassLoadingStrategy;
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
import org.mockito.exceptions.base.MockitoException;
import org.mockito.internal.creation.bytebuddy.SubclassLoader;
+import java.io.File;
+
+import static org.mockito.internal.util.StringUtil.join;
+
class AndroidLoadingStrategy implements SubclassLoader {
@Override
- public ClassLoadingStrategy<ClassLoader> getStrategy(Class<?> mockFeatures) {
+ public ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean codegen) {
File target = AndroidTempFileLocator.target;
if (target == null) {
throw new MockitoException(join(
diff --git a/subprojects/inline/src/test/java/org/mockitoinline/FinalClassMockingTest.java b/subprojects/inline/src/test/java/org/mockitoinline/FinalClassMockingTest.java
index 0f2ea78..80c9de8 100644
--- a/subprojects/inline/src/test/java/org/mockitoinline/FinalClassMockingTest.java
+++ b/subprojects/inline/src/test/java/org/mockitoinline/FinalClassMockingTest.java
@@ -9,6 +9,7 @@
public class FinalClassMockingTest {
+ @SuppressWarnings("CheckReturnValue")
@Test
public void no_exception_while_mocking_final_class() throws Exception {
Mockito.mock(FinalClass.class);