diff options
author | Dan Shi <dshi@google.com> | 2019-07-30 20:07:42 +0000 |
---|---|---|
committer | Dan Shi <dshi@google.com> | 2019-07-30 20:36:03 +0000 |
commit | 5ea495ad0abda02b77b02cca21182b075a6bc8d6 (patch) | |
tree | 0f7c162e8073c7f326ee4ac29a496c4262d9c086 /src/main/java | |
parent | feedf5422d04e9d37a8f7c8e76d17f2cf7378924 (diff) | |
download | mockito-5ea495ad0abda02b77b02cca21182b075a6bc8d6.tar.gz |
Revert "Update to Mockito v2.25.7."
This reverts commit feedf5422d04e9d37a8f7c8e76d17f2cf7378924.
Reason for revert: b/138648173
Change-Id: I21b2147346f42bb35ef263f333ff08f1b1216ae3
Exempt-From-Owner-Approval: fix tot
Diffstat (limited to 'src/main/java')
84 files changed, 385 insertions, 1840 deletions
diff --git a/src/main/java/org/mockito/AdditionalAnswers.java b/src/main/java/org/mockito/AdditionalAnswers.java index 6274fd7..214eaa5 100644 --- a/src/main/java/org/mockito/AdditionalAnswers.java +++ b/src/main/java/org/mockito/AdditionalAnswers.java @@ -16,13 +16,11 @@ import org.mockito.stubbing.Answer2; import org.mockito.stubbing.Answer3; import org.mockito.stubbing.Answer4; import org.mockito.stubbing.Answer5; -import org.mockito.stubbing.Answer6; import org.mockito.stubbing.VoidAnswer1; import org.mockito.stubbing.VoidAnswer2; import org.mockito.stubbing.VoidAnswer3; import org.mockito.stubbing.VoidAnswer4; import org.mockito.stubbing.VoidAnswer5; -import org.mockito.stubbing.VoidAnswer6; import static org.mockito.internal.stubbing.answers.AnswerFunctionalInterfaces.toAnswer; @@ -490,43 +488,4 @@ public class AdditionalAnswers { public static <A, B, C, D, E> Answer<Void> answerVoid(VoidAnswer5<A, B, C, D, E> answer) { return toAnswer(answer); } - - /** - * Creates an answer from a functional interface - allows for a strongly typed answer to be created - * idiomatically in Java 8 - * - * @param answer interface to the answer - which is expected to return something - * @param <T> return type - * @param <A> input parameter type 1 - * @param <B> input parameter type 2 - * @param <C> input parameter type 3 - * @param <D> input parameter type 4 - * @param <E> input parameter type 5 - * @param <F> input parameter type 6 - * @return the answer object to use - * @since 2.26.0 - */ - @Incubating - public static <T, A, B, C, D, E, F> Answer<T> answer(Answer6<T, A, B, C, D, E, F> answer) { - return toAnswer(answer); - } - - /** - * Creates an answer from a functional interface - allows for a strongly typed answer to be created - * idiomatically in Java 8 - * - * @param answer interface to the answer - a void method - * @param <A> input parameter type 1 - * @param <B> input parameter type 2 - * @param <C> input parameter type 3 - * @param <D> input parameter type 4 - * @param <E> input parameter type 5 - * @param <F> input parameter type 6 - * @return the answer object to use - * @since 2.26.0 - */ - @Incubating - public static <A, B, C, D, E, F> Answer<Void> answerVoid(VoidAnswer6<A, B, C, D, E, F> answer) { - return toAnswer(answer); - } } diff --git a/src/main/java/org/mockito/ArgumentCaptor.java b/src/main/java/org/mockito/ArgumentCaptor.java index 7011c92..1104de9 100644 --- a/src/main/java/org/mockito/ArgumentCaptor.java +++ b/src/main/java/org/mockito/ArgumentCaptor.java @@ -49,7 +49,7 @@ import org.mockito.internal.matchers.CapturingMatcher; * Custom argument matchers via {@link ArgumentMatcher} are usually better for stubbing. * * <p> - * This utility class <strong>*doesn't do any type checks*</strong>. The generic signatures are only there to avoid casting + * This utility class <strong>*don't do any type checks*</strong>, the generic signatures are only there to avoid casting * in your code. * <p> * There is an <strong>annotation</strong> that you might find useful: @{@link Captor} @@ -136,7 +136,7 @@ public class ArgumentCaptor<T> { /** * Build a new <code>ArgumentCaptor</code>. * <p> - * Note that an <code>ArgumentCaptor</code> <b>*doesn't do any type checks*</b>. It is only there to avoid casting + * Note that an <code>ArgumentCaptor</code> <b>*don't do any type checks*</b>, it is only there to avoid casting * in your code. This might however change (type checks could be added) in a * future major release. * diff --git a/src/main/java/org/mockito/ArgumentMatchers.java b/src/main/java/org/mockito/ArgumentMatchers.java index e2b83c8..4a6c84d 100644 --- a/src/main/java/org/mockito/ArgumentMatchers.java +++ b/src/main/java/org/mockito/ArgumentMatchers.java @@ -521,7 +521,6 @@ public class ArgumentMatchers { * @deprecated With Java 8 this method will be removed in Mockito 3.0. This method is only used for generic * friendliness to avoid casting, this is not anymore needed in Java 8. */ - @Deprecated public static <T> List<T> anyListOf(Class<T> clazz) { return anyList(); } @@ -582,7 +581,6 @@ public class ArgumentMatchers { * @deprecated With Java 8 this method will be removed in Mockito 3.0. This method is only used for generic * friendliness to avoid casting, this is not anymore needed in Java 8. */ - @Deprecated public static <T> Set<T> anySetOf(Class<T> clazz) { return anySet(); } @@ -644,7 +642,6 @@ public class ArgumentMatchers { * @deprecated With Java 8 this method will be removed in Mockito 3.0. This method is only used for generic * friendliness to avoid casting, this is not anymore needed in Java 8. */ - @Deprecated public static <K, V> Map<K, V> anyMapOf(Class<K> keyClazz, Class<V> valueClazz) { return anyMap(); } @@ -705,7 +702,6 @@ public class ArgumentMatchers { * @deprecated With Java 8 this method will be removed in Mockito 3.0. This method is only used for generic * friendliness to avoid casting, this is not anymore needed in Java 8. */ - @Deprecated public static <T> Collection<T> anyCollectionOf(Class<T> clazz) { return anyCollection(); } @@ -768,7 +764,6 @@ public class ArgumentMatchers { * @deprecated With Java 8 this method will be removed in Mockito 3.0. This method is only used for generic * friendliness to avoid casting, this is not anymore needed in Java 8. */ - @Deprecated public static <T> Iterable<T> anyIterableOf(Class<T> clazz) { return anyIterable(); } @@ -993,7 +988,6 @@ public class ArgumentMatchers { * @deprecated With Java 8 this method will be removed in Mockito 3.0. This method is only used for generic * friendliness to avoid casting, this is not anymore needed in Java 8. */ - @Deprecated public static <T> T isNull(Class<T> clazz) { return isNull(); } @@ -1037,7 +1031,6 @@ public class ArgumentMatchers { * @deprecated With Java 8 this method will be removed in Mockito 3.0. This method is only used for generic * friendliness to avoid casting, this is not anymore needed in Java 8. */ - @Deprecated public static <T> T notNull(Class<T> clazz) { return notNull(); } @@ -1079,7 +1072,6 @@ public class ArgumentMatchers { * @deprecated With Java 8 this method will be removed in Mockito 3.0. This method is only used for generic * friendliness to avoid casting, this is not anymore needed in Java 8. */ - @Deprecated public static <T> T isNotNull(Class<T> clazz) { return notNull(clazz); } diff --git a/src/main/java/org/mockito/Mock.java b/src/main/java/org/mockito/Mock.java index 1c6cbb8..909432f 100644 --- a/src/main/java/org/mockito/Mock.java +++ b/src/main/java/org/mockito/Mock.java @@ -9,7 +9,6 @@ import java.lang.annotation.Retention; import java.lang.annotation.Target; import org.mockito.junit.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.PARAMETER; @@ -68,41 +67,13 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; @Documented public @interface Mock { - /** - * Mock will have custom answer, see {@link MockSettings#defaultAnswer(Answer)}. - * For examples how to use 'Mock' annotation and parameters see {@link Mock}. - */ Answers answer() default Answers.RETURNS_DEFAULTS; - /** - * Mock will be 'stubOnly', see {@link MockSettings#stubOnly()}. - * For examples how to use 'Mock' annotation and parameters see {@link Mock}. - */ boolean stubOnly() default false; - /** - * Mock will have custom name (shown in verification errors), see {@link MockSettings#name(String)}. - * For examples how to use 'Mock' annotation and parameters see {@link Mock}. - */ String name() default ""; - /** - * Mock will have extra interfaces, see {@link MockSettings#extraInterfaces(Class[])}. - * For examples how to use 'Mock' annotation and parameters see {@link Mock}. - */ Class<?>[] extraInterfaces() default {}; - /** - * Mock will be serializable, see {@link MockSettings#serializable()}. - * For examples how to use 'Mock' annotation and parameters see {@link Mock}. - */ boolean serializable() default false; - - /** - * Mock will be lenient, see {@link MockSettings#lenient()}. - * For examples how to use 'Mock' annotation and parameters see {@link Mock}. - * - * @since 2.23.3 - */ - boolean lenient() default false; } diff --git a/src/main/java/org/mockito/MockSettings.java b/src/main/java/org/mockito/MockSettings.java index 07af55e..c79c243 100644 --- a/src/main/java/org/mockito/MockSettings.java +++ b/src/main/java/org/mockito/MockSettings.java @@ -9,7 +9,6 @@ import org.mockito.exceptions.misusing.UnnecessaryStubbingException; import org.mockito.invocation.InvocationFactory; import org.mockito.invocation.MockHandler; import org.mockito.listeners.InvocationListener; -import org.mockito.listeners.StubbingLookupListener; import org.mockito.listeners.VerificationStartedListener; import org.mockito.mock.MockCreationSettings; import org.mockito.mock.SerializableMode; @@ -44,7 +43,6 @@ import java.io.Serializable; * Firstly, to make it easy to add another mock setting when the demand comes. * Secondly, to enable combining together different mock settings without introducing zillions of overloaded mock() methods. */ -@NotExtensible public interface MockSettings extends Serializable { /** @@ -206,24 +204,6 @@ public interface MockSettings extends Serializable { MockSettings verboseLogging(); /** - * Add stubbing lookup listener to the mock object. - * - * Multiple listeners may be added and they will be notified orderly. - * - * For use cases and more info see {@link StubbingLookupListener}. - * - * Example: - * <pre class="code"><code class="java"> - * List mockWithListener = mock(List.class, withSettings().stubbingLookupListeners(new YourStubbingLookupListener())); - * </code></pre> - * - * @param listeners The stubbing lookup listeners to add. May not be null. - * @return settings instance so that you can fluently specify other settings - * @since 2.24.6 - */ - MockSettings stubbingLookupListeners(StubbingLookupListener... listeners); - - /** * Registers a listener for method invocations on this mock. The listener is * notified every time a method on this mock is called. * <p> diff --git a/src/main/java/org/mockito/Mockito.java b/src/main/java/org/mockito/Mockito.java index 5066eec..2d06e58 100644 --- a/src/main/java/org/mockito/Mockito.java +++ b/src/main/java/org/mockito/Mockito.java @@ -103,8 +103,7 @@ import org.mockito.verification.VerificationWithTimeout; * <a href="#43">43. 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 JUnit Jupiter (JUnit5+) extension</a><br/> - * <a href="#46">46. New <code>Mockito.lenient()</code> and <code>MockSettings.lenient()</code> methods (Since 2.20.0)</a><br/> - * <a href="#47">47. New API for clearing mock state in inline mocking (Since 2.25.0)</a><br/> + * <a href="#46">46. New <code>Mockito.lenient()</code> and <code>MockSettings.lenient()</code> methods (Since 2.20.0</a><br/> * </b> * * <h3 id="0">0. <a class="meaningful_link" href="#mockito2" name="mockito2">Migrating to Mockito 2</a></h3> @@ -208,7 +207,7 @@ import org.mockito.verification.VerificationWithTimeout; * * //Although it is possible to verify a stubbed invocation, usually <b>it's just redundant</b> * //If your code cares what get(0) returns, then something else breaks (often even before verify() gets executed). - * //If your code doesn't care what get(0) returns, then it should not be stubbed. + * //If your code doesn't care what get(0) returns, then it should not be stubbed. Not convinced? See <a href="http://monkeyisland.pl/2008/04/26/asking-and-telling">here</a>. * verify(mockedList).get(0); * </code></pre> * @@ -358,7 +357,7 @@ import org.mockito.verification.VerificationWithTimeout; * //create an inOrder verifier for a single mock * InOrder inOrder = inOrder(singleMock); * - * //following will make sure that add is first called with "was added first", then with "was added second" + * //following will make sure that add is first called with "was added first, then with "was added second" * inOrder.verify(singleMock).add("was added first"); * inOrder.verify(singleMock).add("was added second"); * @@ -427,7 +426,8 @@ import org.mockito.verification.VerificationWithTimeout; * Some users who did a lot of classic, expect-run-verify mocking tend to use <code>verifyNoMoreInteractions()</code> very often, even in every test method. * <code>verifyNoMoreInteractions()</code> is not recommended to use in every test method. * <code>verifyNoMoreInteractions()</code> is a handy assertion from the interaction testing toolkit. Use it only when it's relevant. - * Abusing it leads to <strong>overspecified</strong>, <strong>less maintainable</strong> tests. + * Abusing it leads to <strong>overspecified</strong>, <strong>less maintainable</strong> tests. You can find further reading + * <a href="http://monkeyisland.pl/2008/07/12/should-i-worry-about-the-unexpected/">here</a>. * * <p> * See also {@link Mockito#never()} - it is more explicit and @@ -464,7 +464,6 @@ import org.mockito.verification.VerificationWithTimeout; * </code></pre> * * You can use built-in runner: {@link MockitoJUnitRunner} or a rule: {@link MockitoRule}. - * For JUnit5 tests, refer to the JUnit5 extension described in <a href="#45">section 45</a>. * <p> * Read more here: {@link MockitoAnnotations} * @@ -598,7 +597,8 @@ import org.mockito.verification.VerificationWithTimeout; * <b>Before the release 1.8</b>, Mockito spies were not real partial mocks. * The reason was we thought partial mock is a code smell. * At some point we found legitimate use cases for partial mocks - * (3rd party interfaces, interim refactoring of legacy code). + * (3rd party interfaces, interim refactoring of legacy code, the full article is + * <a href="http://monkeyisland.pl/2009/01/13/subclass-and-override-vs-partial-mocking-vs-refactoring">here</a>) * <p> * * <pre class="code"><code class="java"> @@ -707,7 +707,8 @@ import org.mockito.verification.VerificationWithTimeout; * <h3 id="16">16. <a class="meaningful_link" href="#partial_mocks" name="partial_mocks">Real partial mocks</a> (Since 1.8.0)</h3> * * Finally, after many internal debates & discussions on the mailing list, partial mock support was added to Mockito. - * Previously we considered partial mocks as code smells. However, we found a legitimate use case for partial mocks. + * Previously we considered partial mocks as code smells. However, we found a legitimate use case for partial mocks - more reading: + * <a href="http://monkeyisland.pl/2009/01/13/subclass-and-override-vs-partial-mocking-vs-refactoring">here</a> * <p> * <b>Before release 1.8</b> <code>spy()</code> was not producing real partial mocks and it was confusing for some users. * Read more about spying: <a href="#13">here</a> or in javadoc for {@link Mockito#spy(Object)} method. @@ -1531,15 +1532,6 @@ import org.mockito.verification.VerificationWithTimeout; * * For more information refer to {@link Mockito#lenient()}. * Let us know how do you find the new feature by opening a GitHub issue to discuss! - * - * <h3 id="47">47. <a class="meaningful_link" href="#clear_inline_mocks" name="clear_inline_mocks">New API for clearing mock state in inline mocking (Since 2.25.0)</a></h3> - * - * In certain specific, rare scenarios (issue <a href="https://github.com/mockito/mockito/pull/1619">#1619</a>) - * inline mocking causes memory leaks. - * There is no clean way to mitigate this problem completely. - * Hence, we introduced a new API to explicitly clear mock state (only make sense in inline mocking!). - * See example usage in {@link MockitoFramework#clearInlineMocks()}. - * If you have feedback or a better idea how to solve the problem please reach out. */ @SuppressWarnings("unchecked") public class Mockito extends ArgumentMatchers { @@ -1692,7 +1684,6 @@ public class Mockito extends ArgumentMatchers { /** * Optional <code>Answer</code> to be used with {@link Mockito#mock(Class, Answer)} - * * <p> * {@link Answer} can be used to define the return values of unstubbed invocations. * <p> @@ -1724,11 +1715,8 @@ public class Mockito extends ArgumentMatchers { * </code></pre> * * <p> - * <u>Note 1:</u> Stubbing partial mocks using <code>when(mock.getSomething()).thenReturn(fakeValue)</code> + * <u>Note:</u> Stubbing partial mocks using <code>when(mock.getSomething()).thenReturn(fakeValue)</code> * syntax will call the real method. For partial mock it's recommended to use <code>doReturn</code> syntax. - * <p> - * <u>Note 2:</u> If the mock is serialized then deserialized, then this answer will not be able to understand - * generics metadata. */ public static final Answer<Object> CALLS_REAL_METHODS = Answers.CALLS_REAL_METHODS; @@ -2081,6 +2069,7 @@ public class Mockito extends ArgumentMatchers { * Let's say you've stubbed <code>foo.bar()</code>. * If your code cares what <code>foo.bar()</code> returns then something else breaks(often before even <code>verify()</code> gets executed). * If your code doesn't care what <code>get(0)</code> returns then it should not be stubbed. + * Not convinced? See <a href="http://monkeyisland.pl/2008/04/26/asking-and-telling">here</a>. * * <p> * See examples in javadoc for {@link Mockito} class @@ -2112,6 +2101,7 @@ public class Mockito extends ArgumentMatchers { * Let's say you've stubbed <code>foo.bar()</code>. * If your code cares what <code>foo.bar()</code> returns then something else breaks(often before even <code>verify()</code> gets executed). * If your code doesn't care what <code>get(0)</code> returns then it should not be stubbed. + * Not convinced? See <a href="http://monkeyisland.pl/2008/04/26/asking-and-telling">here</a>. * * <p> * See examples in javadoc for {@link Mockito} class @@ -2213,7 +2203,8 @@ public class Mockito extends ArgumentMatchers { * Some users who did a lot of classic, expect-run-verify mocking tend to use <code>verifyNoMoreInteractions()</code> very often, even in every test method. * <code>verifyNoMoreInteractions()</code> is not recommended to use in every test method. * <code>verifyNoMoreInteractions()</code> is a handy assertion from the interaction testing toolkit. Use it only when it's relevant. - * Abusing it leads to overspecified, less maintainable tests. + * Abusing it leads to overspecified, less maintainable tests. You can find further reading + * <a href="http://monkeyisland.pl/2008/07/12/should-i-worry-about-the-unexpected/">here</a>. * <p> * This method will also detect unverified invocations that occurred before the test method, * for example: in <code>setUp()</code>, <code>@Before</code> method or in constructor. diff --git a/src/main/java/org/mockito/MockitoFramework.java b/src/main/java/org/mockito/MockitoFramework.java index da03ef4..5ffe272 100644 --- a/src/main/java/org/mockito/MockitoFramework.java +++ b/src/main/java/org/mockito/MockitoFramework.java @@ -20,7 +20,6 @@ import org.mockito.plugins.MockitoPlugins; * @since 2.1.0 */ @Incubating -@NotExtensible public interface MockitoFramework { /** @@ -93,55 +92,4 @@ public interface MockitoFramework { */ @Incubating InvocationFactory getInvocationFactory(); - - /** - * Clears up internal state of all inline mocks. - * This method is only meaningful if inline mock maker is in use. - * Otherwise this method is a no-op and need not be used. - * <p> - * This method is useful to tackle subtle memory leaks that are possible due to the nature of inline mocking - * (issue <a href="https://github.com/mockito/mockito/pull/1619">#1619</a>). - * If you are facing those problems, call this method at the end of the test (or in "@After" method). - * See examples of using "clearInlineMocks" in Mockito test code. - * To find out why inline mock maker keeps track of the mock objects see {@link org.mockito.plugins.InlineMockMaker}. - * <p> - * Mockito's "inline mocking" enables mocking final types, enums and final methods - * (read more in section 39 of {@link Mockito} javadoc). - * This method is only meaningful when {@link org.mockito.plugins.InlineMockMaker} is in use. - * If you're using a different {@link org.mockito.plugins.MockMaker} then this method is a no-op. - * - * <pre class="code"><code class="java"> - * public class ExampleTest { - * - * @After - * public void clearMocks() { - * Mockito.framework().clearInlineMocks(); - * } - * - * @Test - * public void someTest() { - * ... - * } - * } - * </pre> - * - * If you have feedback or a better idea how to solve the problem please reach out. - * - * @since 2.25.0 - * @see #clearInlineMock(Object) - */ - @Incubating - void clearInlineMocks(); - - /** - * Clears up internal state of specific inline mock. - * This method is a single-mock variant of {@link #clearInlineMocks()}. - * Please read javadoc for {@link #clearInlineMocks()}. - * - * @param mock to clear up - * @since 2.25.0 - * @see #clearInlineMocks() - */ - @Incubating - void clearInlineMock(Object mock); } diff --git a/src/main/java/org/mockito/MockitoSession.java b/src/main/java/org/mockito/MockitoSession.java index 6a529fd..9e820f2 100644 --- a/src/main/java/org/mockito/MockitoSession.java +++ b/src/main/java/org/mockito/MockitoSession.java @@ -88,7 +88,6 @@ import org.mockito.session.MockitoSessionBuilder; * @since 2.7.0 */ @Incubating -@NotExtensible public interface MockitoSession { /** diff --git a/src/main/java/org/mockito/exceptions/misusing/InjectMocksException.java b/src/main/java/org/mockito/exceptions/misusing/InjectMocksException.java deleted file mode 100644 index 616d4b6..0000000 --- a/src/main/java/org/mockito/exceptions/misusing/InjectMocksException.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2018 Mockito contributors - * This program is made available under the terms of the MIT License. - */ -package org.mockito.exceptions.misusing; - -import org.mockito.exceptions.base.MockitoException; - -/** - * Thrown when creation of test subject annotated with InjectMocks fails. - */ -public class InjectMocksException extends MockitoException { - public InjectMocksException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/src/main/java/org/mockito/exceptions/verification/ArgumentsAreDifferent.java b/src/main/java/org/mockito/exceptions/verification/ArgumentsAreDifferent.java index 5a72f20..a44cc6f 100644 --- a/src/main/java/org/mockito/exceptions/verification/ArgumentsAreDifferent.java +++ b/src/main/java/org/mockito/exceptions/verification/ArgumentsAreDifferent.java @@ -17,19 +17,6 @@ public class ArgumentsAreDifferent extends MockitoAssertionError { super(message); } - /** - * Three-arg constructor for compatibility with ExceptionFactory's three-arg - * create method. This implementation simply ignores the second and third - * arguments. - * - * @param message - * @param wanted ignored - * @param actual ignored - */ - public ArgumentsAreDifferent(String message, String wanted, String actual) { - this(message); - } - @Override public String toString() { return removeFirstLine(super.toString()); diff --git a/src/main/java/org/mockito/exceptions/verification/junit/package-info.java b/src/main/java/org/mockito/exceptions/verification/junit/package-info.java index ad4ab77..4542d34 100644 --- a/src/main/java/org/mockito/exceptions/verification/junit/package-info.java +++ b/src/main/java/org/mockito/exceptions/verification/junit/package-info.java @@ -4,9 +4,6 @@ */ /** - * JUnit integration to provide better support for JUnit 4 and - * earlier in IDEs. - * - * @see org.mockito.exceptions.verification.opentest4j + * JUnit integration to provide better support for junit runners in IDEs. */ package org.mockito.exceptions.verification.junit; diff --git a/src/main/java/org/mockito/exceptions/verification/opentest4j/ArgumentsAreDifferent.java b/src/main/java/org/mockito/exceptions/verification/opentest4j/ArgumentsAreDifferent.java deleted file mode 100644 index 8f50d00..0000000 --- a/src/main/java/org/mockito/exceptions/verification/opentest4j/ArgumentsAreDifferent.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2019 Mockito contributors - * This program is made available under the terms of the MIT License. - */ - -package org.mockito.exceptions.verification.opentest4j; - -import static org.mockito.internal.util.StringUtil.removeFirstLine; - -import org.mockito.internal.exceptions.stacktrace.ConditionalStackTraceFilter; -import org.opentest4j.AssertionFailedError; - - -public class ArgumentsAreDifferent extends AssertionFailedError { - - private static final long serialVersionUID = 1L; - private final String message; - private final StackTraceElement[] unfilteredStackTrace; - - public ArgumentsAreDifferent(String message, String wanted, String actual) { - super(message, wanted, actual); - this.message = message; - - unfilteredStackTrace = getStackTrace(); - ConditionalStackTraceFilter filter = new ConditionalStackTraceFilter(); - filter.filter(this); - } - - @Override - public String getMessage() { - return message; - } - - public StackTraceElement[] getUnfilteredStackTrace() { - return unfilteredStackTrace; - } - - @Override - public String toString() { - return removeFirstLine(super.toString()); - } -} diff --git a/src/main/java/org/mockito/exceptions/verification/opentest4j/package-info.java b/src/main/java/org/mockito/exceptions/verification/opentest4j/package-info.java deleted file mode 100644 index 2e84ddd..0000000 --- a/src/main/java/org/mockito/exceptions/verification/opentest4j/package-info.java +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (c) 2019 Mockito contributors - * This program is made available under the terms of the MIT License. - */ - -/** - * Integration to provide better support for IDEs that support OpenTest4J. - * - * @see org.mocktio.exceptions.verification.junit - * @see org.mocktio.exceptions.verification.junit4 - */ -package org.mockito.exceptions.verification.opentest4j; diff --git a/src/main/java/org/mockito/internal/MockitoCore.java b/src/main/java/org/mockito/internal/MockitoCore.java index 5d39d5e..68b580a 100644 --- a/src/main/java/org/mockito/internal/MockitoCore.java +++ b/src/main/java/org/mockito/internal/MockitoCore.java @@ -35,17 +35,24 @@ import org.mockito.verification.VerificationMode; import java.util.Arrays; import java.util.List; -import static org.mockito.internal.exceptions.Reporter.*; +import static org.mockito.internal.exceptions.Reporter.missingMethodInvocation; +import static org.mockito.internal.exceptions.Reporter.mocksHaveToBePassedToVerifyNoMoreInteractions; +import static org.mockito.internal.exceptions.Reporter.mocksHaveToBePassedWhenCreatingInOrder; +import static org.mockito.internal.exceptions.Reporter.notAMockPassedToVerify; +import static org.mockito.internal.exceptions.Reporter.notAMockPassedToVerifyNoMoreInteractions; +import static org.mockito.internal.exceptions.Reporter.notAMockPassedWhenCreatingInOrder; +import static org.mockito.internal.exceptions.Reporter.nullPassedToVerify; +import static org.mockito.internal.exceptions.Reporter.nullPassedToVerifyNoMoreInteractions; +import static org.mockito.internal.exceptions.Reporter.nullPassedWhenCreatingInOrder; +import static org.mockito.internal.exceptions.Reporter.stubPassedToVerify; import static org.mockito.internal.progress.ThreadSafeMockingProgress.mockingProgress; import static org.mockito.internal.util.MockUtil.createMock; import static org.mockito.internal.util.MockUtil.getInvocationContainer; -import static org.mockito.internal.util.MockUtil.getMockHandler; import static org.mockito.internal.util.MockUtil.isMock; import static org.mockito.internal.util.MockUtil.resetMock; import static org.mockito.internal.util.MockUtil.typeMockabilityOf; import static org.mockito.internal.verification.VerificationModeFactory.noMoreInteractions; - @SuppressWarnings("unchecked") public class MockitoCore { @@ -84,8 +91,10 @@ public class MockitoCore { if (!mockingDetails.isMock()) { throw notAMockPassedToVerify(mock.getClass()); } - assertNotStubOnlyMock(mock); MockHandler handler = mockingDetails.getMockHandler(); + if (handler.getMockSettings().isStubOnly()) { + throw stubPassedToVerify(); + } mock = (T) VerificationStartedNotifier.notifyVerificationStarted( handler.getMockSettings().getVerificationStartedListeners(), mockingDetails); @@ -126,7 +135,6 @@ public class MockitoCore { throw nullPassedToVerifyNoMoreInteractions(); } InvocationContainerImpl invocations = getInvocationContainer(mock); - assertNotStubOnlyMock(mock); VerificationDataImpl data = new VerificationDataImpl(invocations, null); noMoreInteractions().verify(data); } catch (NotAMockException e) { @@ -147,12 +155,6 @@ public class MockitoCore { } } - private void assertNotStubOnlyMock(Object mock) { - if (getMockHandler(mock).getMockSettings().isStubOnly()) { - throw stubPassedToVerify(mock); - } - } - public InOrder inOrder(Object... mocks) { if (mocks == null || mocks.length == 0) { throw mocksHaveToBePassedWhenCreatingInOrder(); @@ -164,7 +166,6 @@ public class MockitoCore { if (!isMock(mock)) { throw notAMockPassedWhenCreatingInOrder(); } - assertNotStubOnlyMock(mock); } return new InOrderImpl(Arrays.asList(mocks)); } diff --git a/src/main/java/org/mockito/internal/configuration/InjectingAnnotationEngine.java b/src/main/java/org/mockito/internal/configuration/InjectingAnnotationEngine.java index 20d967d..6cb5fb1 100644 --- a/src/main/java/org/mockito/internal/configuration/InjectingAnnotationEngine.java +++ b/src/main/java/org/mockito/internal/configuration/InjectingAnnotationEngine.java @@ -39,7 +39,15 @@ public class InjectingAnnotationEngine implements AnnotationEngine, org.mockito. */ public void process(Class<?> clazz, Object testInstance) { processIndependentAnnotations(testInstance.getClass(), testInstance); - injectMocks(testInstance); + processInjectMocks(testInstance.getClass(), testInstance); + } + + private void processInjectMocks(final Class<?> clazz, final Object testInstance) { + Class<?> classContext = clazz; + while (classContext != Object.class) { + injectMocks(testInstance); + classContext = classContext.getSuperclass(); + } } private void processIndependentAnnotations(final Class<?> clazz, final Object testInstance) { diff --git a/src/main/java/org/mockito/internal/configuration/MockAnnotationProcessor.java b/src/main/java/org/mockito/internal/configuration/MockAnnotationProcessor.java index d99b348..91086d2 100644 --- a/src/main/java/org/mockito/internal/configuration/MockAnnotationProcessor.java +++ b/src/main/java/org/mockito/internal/configuration/MockAnnotationProcessor.java @@ -35,9 +35,6 @@ public class MockAnnotationProcessor implements FieldAnnotationProcessor<Mock> { if(annotation.stubOnly()){ mockSettings.stubOnly(); } - if(annotation.lenient()){ - mockSettings.lenient(); - } // see @Mock answer default value mockSettings.defaultAnswer(annotation.answer()); diff --git a/src/main/java/org/mockito/internal/configuration/plugins/DefaultMockitoPlugins.java b/src/main/java/org/mockito/internal/configuration/plugins/DefaultMockitoPlugins.java index e5aefd9..f80e7c4 100644 --- a/src/main/java/org/mockito/internal/configuration/plugins/DefaultMockitoPlugins.java +++ b/src/main/java/org/mockito/internal/configuration/plugins/DefaultMockitoPlugins.java @@ -9,7 +9,6 @@ import org.mockito.plugins.AnnotationEngine; import org.mockito.plugins.InstantiatorProvider; import org.mockito.plugins.InstantiatorProvider2; import org.mockito.plugins.MockMaker; -import org.mockito.plugins.MockitoLogger; import org.mockito.plugins.MockitoPlugins; import org.mockito.plugins.PluginSwitch; import org.mockito.plugins.StackTraceCleanerProvider; @@ -30,7 +29,6 @@ class DefaultMockitoPlugins implements MockitoPlugins { DEFAULT_PLUGINS.put(InstantiatorProvider2.class.getName(), "org.mockito.internal.creation.instance.DefaultInstantiatorProvider"); DEFAULT_PLUGINS.put(AnnotationEngine.class.getName(), "org.mockito.internal.configuration.InjectingAnnotationEngine"); DEFAULT_PLUGINS.put(INLINE_ALIAS, "org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker"); - DEFAULT_PLUGINS.put(MockitoLogger.class.getName(), "org.mockito.internal.util.ConsoleMockitoLogger"); } @Override diff --git a/src/main/java/org/mockito/internal/configuration/plugins/PluginRegistry.java b/src/main/java/org/mockito/internal/configuration/plugins/PluginRegistry.java index 2e5f069..02e5d66 100644 --- a/src/main/java/org/mockito/internal/configuration/plugins/PluginRegistry.java +++ b/src/main/java/org/mockito/internal/configuration/plugins/PluginRegistry.java @@ -9,7 +9,6 @@ import org.mockito.plugins.AnnotationEngine; import org.mockito.plugins.InstantiatorProvider; import org.mockito.plugins.InstantiatorProvider2; import org.mockito.plugins.MockMaker; -import org.mockito.plugins.MockitoLogger; import org.mockito.plugins.PluginSwitch; import org.mockito.plugins.StackTraceCleanerProvider; @@ -26,12 +25,9 @@ class PluginRegistry { private final InstantiatorProvider2 instantiatorProvider; - private final AnnotationEngine annotationEngine = new PluginLoader(pluginSwitch) + private AnnotationEngine annotationEngine = new PluginLoader(pluginSwitch) .loadPlugin(AnnotationEngine.class); - private final MockitoLogger mockitoLogger = new PluginLoader(pluginSwitch) - .loadPlugin(MockitoLogger.class); - PluginRegistry() { Object impl = new PluginLoader(pluginSwitch).loadPlugin(InstantiatorProvider2.class, InstantiatorProvider.class); if (impl instanceof InstantiatorProvider) { @@ -79,14 +75,4 @@ class PluginRegistry { AnnotationEngine getAnnotationEngine() { return annotationEngine; } - - /** - * Returns the logger available for the current runtime. - * - * <p>Returns {@link org.mockito.internal.util.ConsoleMockitoLogger} if no - * {@link org.mockito.plugins.MockitoLogger} extension exists or is visible in the current classpath.</p> - */ - MockitoLogger getMockitoLogger() { - return mockitoLogger; - } } diff --git a/src/main/java/org/mockito/internal/configuration/plugins/Plugins.java b/src/main/java/org/mockito/internal/configuration/plugins/Plugins.java index 84e3c0d..f65fe89 100644 --- a/src/main/java/org/mockito/internal/configuration/plugins/Plugins.java +++ b/src/main/java/org/mockito/internal/configuration/plugins/Plugins.java @@ -4,7 +4,6 @@ */ package org.mockito.internal.configuration.plugins; -import org.mockito.plugins.MockitoLogger; import org.mockito.plugins.AnnotationEngine; import org.mockito.plugins.InstantiatorProvider2; import org.mockito.plugins.MockMaker; @@ -57,16 +56,6 @@ public class Plugins { } /** - * Returns the logger available for the current runtime. - * - * <p>Returns {@link org.mockito.internal.util.ConsoleMockitoLogger} if no - * {@link org.mockito.plugins.MockitoLogger} extension exists or is visible in the current classpath.</p> - */ - public static MockitoLogger getMockitoLogger() { - return registry.getMockitoLogger(); - } - - /** * @return instance of mockito plugins type */ public static MockitoPlugins getPlugins() { diff --git a/src/main/java/org/mockito/internal/creation/MockSettingsImpl.java b/src/main/java/org/mockito/internal/creation/MockSettingsImpl.java index 50134b4..ca67730 100644 --- a/src/main/java/org/mockito/internal/creation/MockSettingsImpl.java +++ b/src/main/java/org/mockito/internal/creation/MockSettingsImpl.java @@ -11,7 +11,6 @@ import org.mockito.internal.util.Checks; import org.mockito.internal.util.MockCreationValidator; import org.mockito.internal.util.MockNameImpl; import org.mockito.listeners.InvocationListener; -import org.mockito.listeners.StubbingLookupListener; import org.mockito.listeners.VerificationStartedListener; import org.mockito.mock.MockCreationSettings; import org.mockito.mock.MockName; @@ -20,17 +19,17 @@ import org.mockito.stubbing.Answer; import java.io.Serializable; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; -import static java.util.Arrays.asList; import static org.mockito.internal.exceptions.Reporter.defaultAnswerDoesNotAcceptNullParameter; import static org.mockito.internal.exceptions.Reporter.extraInterfacesAcceptsOnlyInterfaces; import static org.mockito.internal.exceptions.Reporter.extraInterfacesDoesNotAcceptNullParameters; import static org.mockito.internal.exceptions.Reporter.extraInterfacesRequiresAtLeastOneInterface; +import static org.mockito.internal.exceptions.Reporter.invocationListenersRequiresAtLeastOneListener; import static org.mockito.internal.exceptions.Reporter.methodDoesNotAcceptParameter; -import static org.mockito.internal.exceptions.Reporter.requiresAtLeastOneListener; import static org.mockito.internal.util.collections.Sets.newSet; @SuppressWarnings("unchecked") @@ -155,7 +154,7 @@ public class MockSettingsImpl<T> extends CreationSettings<T> implements MockSett } List<Object> resultArgs = new ArrayList<Object>(constructorArgs.length + 1); resultArgs.add(outerClassInstance); - resultArgs.addAll(asList(constructorArgs)); + resultArgs.addAll(Arrays.asList(constructorArgs)); return resultArgs.toArray(new Object[constructorArgs.length + 1]); } @@ -174,23 +173,17 @@ public class MockSettingsImpl<T> extends CreationSettings<T> implements MockSett @Override public MockSettings invocationListeners(InvocationListener... listeners) { + if (listeners == null || listeners.length == 0) { + throw invocationListenersRequiresAtLeastOneListener(); + } addListeners(listeners, invocationListeners, "invocationListeners"); return this; } - @Override - public MockSettings stubbingLookupListeners(StubbingLookupListener... listeners) { - addListeners(listeners, stubbingLookupListeners, "stubbingLookupListeners"); - return this; - } - - static <T> void addListeners(T[] listeners, List<T> container, String method) { + private static <T> void addListeners(T[] listeners, List<T> container, String method) { if (listeners == null) { throw methodDoesNotAcceptParameter(method, "null vararg array."); } - if (listeners.length == 0) { - throw requiresAtLeastOneListener(method); - } for (T listener : listeners) { if (listener == null) { throw methodDoesNotAcceptParameter(method, "null listeners."); @@ -214,8 +207,13 @@ public class MockSettingsImpl<T> extends CreationSettings<T> implements MockSett return false; } + @Override + public List<InvocationListener> getInvocationListeners() { + return this.invocationListeners; + } + public boolean hasInvocationListeners() { - return !getInvocationListeners().isEmpty(); + return !invocationListeners.isEmpty(); } @Override diff --git a/src/main/java/org/mockito/internal/creation/SuspendMethod.java b/src/main/java/org/mockito/internal/creation/SuspendMethod.java index 42ceac6..018bc50 100644 --- a/src/main/java/org/mockito/internal/creation/SuspendMethod.java +++ b/src/main/java/org/mockito/internal/creation/SuspendMethod.java @@ -11,18 +11,12 @@ import java.util.Arrays; * See <a href="https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md#continuation-passing-style">Design docs for details</a>. */ public class SuspendMethod { - private static final String KOTLIN_EXPERIMENTAL_CONTINUATION = "kotlin.coroutines.experimental.Continuation"; - private static final String KOTLIN_CONTINUATION = "kotlin.coroutines.Continuation"; + private static final String KOTLIN_CONTINUATION = "kotlin.coroutines.experimental.Continuation"; public static Class<?>[] trimSuspendParameterTypes(Class<?>[] parameterTypes) { int n = parameterTypes.length; - if (n > 0 && isContinuationType(parameterTypes[n - 1])) + if (n > 0 && parameterTypes[n - 1].getName().equals(KOTLIN_CONTINUATION)) return Arrays.copyOf(parameterTypes, n - 1); return parameterTypes; } - - private static boolean isContinuationType(Class<?> parameterType) { - String name = parameterType.getName(); - return name.equals(KOTLIN_CONTINUATION) || name.equals(KOTLIN_EXPERIMENTAL_CONTINUATION); - } } diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/InlineByteBuddyMockMaker.java b/src/main/java/org/mockito/internal/creation/bytebuddy/InlineByteBuddyMockMaker.java index e99b915..42f10ce 100644 --- a/src/main/java/org/mockito/internal/creation/bytebuddy/InlineByteBuddyMockMaker.java +++ b/src/main/java/org/mockito/internal/creation/bytebuddy/InlineByteBuddyMockMaker.java @@ -14,7 +14,6 @@ import org.mockito.internal.util.Platform; import org.mockito.internal.util.concurrent.WeakConcurrentMap; import org.mockito.invocation.MockHandler; import org.mockito.mock.MockCreationSettings; -import org.mockito.plugins.InlineMockMaker; import java.io.File; import java.io.FileOutputStream; @@ -26,8 +25,6 @@ import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.JarOutputStream; -import javax.tools.ToolProvider; - import static org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.EXCLUDES; import static org.mockito.internal.util.StringUtil.join; @@ -90,7 +87,7 @@ import static org.mockito.internal.util.StringUtil.join; * support this feature. */ @Incubating -public class InlineByteBuddyMockMaker implements ClassCreatingMockMaker, InlineMockMaker { +public class InlineByteBuddyMockMaker implements ClassCreatingMockMaker { private static final Instrumentation INSTRUMENTATION; @@ -112,7 +109,7 @@ public class InlineByteBuddyMockMaker implements ClassCreatingMockMaker, InlineM boot.deleteOnExit(); JarOutputStream outputStream = new JarOutputStream(new FileOutputStream(boot)); try { - String source = "org/mockito/internal/creation/bytebuddy/inject/MockMethodDispatcher"; + String source = "org/mockito/internal/creation/bytebuddy/MockMethodDispatcher"; InputStream inputStream = InlineByteBuddyMockMaker.class.getClassLoader().getResourceAsStream(source + ".raw"); if (inputStream == null) { throw new IllegalStateException(join( @@ -137,7 +134,13 @@ public class InlineByteBuddyMockMaker implements ClassCreatingMockMaker, InlineM } instrumentation.appendToBootstrapClassLoaderSearch(new JarFile(boot)); try { - Class.forName("org.mockito.internal.creation.bytebuddy.inject.MockMethodDispatcher", false, null); + Class<?> dispatcher = Class.forName("org.mockito.internal.creation.bytebuddy.MockMethodDispatcher"); + if (dispatcher.getClassLoader() != null) { + throw new IllegalStateException(join( + "The MockMethodDispatcher must not be loaded manually but must be injected into the bootstrap class loader.", + "", + "The dispatcher class was already loaded by: " + dispatcher.getClassLoader())); + } } catch (ClassNotFoundException cnfe) { throw new IllegalStateException(join( "Mockito failed to inject the MockMethodDispatcher class into the bootstrap class loader", @@ -167,7 +170,7 @@ public class InlineByteBuddyMockMaker implements ClassCreatingMockMaker, InlineM if (INITIALIZATION_ERROR != null) { throw new MockitoInitializationException(join( "Could not initialize inline Byte Buddy mock maker. (This mock maker is not supported on Android.)", - ToolProvider.getSystemJavaCompiler() == null ? "Are you running a JRE instead of a JDK? The inline mock maker needs to be run on a JDK.\n" : "", + "", Platform.describe()), INITIALIZATION_ERROR); } bytecodeGenerator = new TypeCachingBytecodeGenerator(new InlineBytecodeGenerator(INSTRUMENTATION, mocks), true); @@ -273,16 +276,6 @@ public class InlineByteBuddyMockMaker implements ClassCreatingMockMaker, InlineM } @Override - public void clearMock(Object mock) { - mocks.remove(mock); - } - - @Override - public void clearAllMocks() { - mocks.clear(); - } - - @Override public TypeMockability isTypeMockable(final Class<?> type) { return new TypeMockability() { @Override 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 e160e3c..64139c2 100644 --- a/src/main/java/org/mockito/internal/creation/bytebuddy/InlineBytecodeGenerator.java +++ b/src/main/java/org/mockito/internal/creation/bytebuddy/InlineBytecodeGenerator.java @@ -26,17 +26,17 @@ import net.bytebuddy.pool.TypePool; import net.bytebuddy.utility.OpenedClassReader; import net.bytebuddy.utility.RandomString; import org.mockito.exceptions.base.MockitoException; -import org.mockito.internal.creation.bytebuddy.inject.MockMethodDispatcher; import org.mockito.internal.util.concurrent.WeakConcurrentMap; import org.mockito.internal.util.concurrent.WeakConcurrentSet; import org.mockito.mock.SerializableMode; import java.lang.instrument.ClassFileTransformer; import java.lang.instrument.Instrumentation; -import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.security.ProtectionDomain; -import java.util.*; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; import static net.bytebuddy.implementation.MethodDelegation.withDefaultConfiguration; import static net.bytebuddy.implementation.bind.annotation.TargetMethodAnnotationDrivenBinder.ParameterBinder.ForFixedValue.OfConstant.of; @@ -60,12 +60,14 @@ public class InlineBytecodeGenerator implements BytecodeGenerator, ClassFileTran String.class)); private final Instrumentation instrumentation; + private final ByteBuddy byteBuddy; + private final WeakConcurrentSet<Class<?>> mocked; + private final BytecodeGenerator subclassEngine; - private final AsmVisitorWrapper mockTransformer; - private final Method getModule, canRead, redefineModule; + private final AsmVisitorWrapper mockTransformer; private volatile Throwable lastException; @@ -96,20 +98,6 @@ public class InlineBytecodeGenerator implements BytecodeGenerator, ClassFileTran Advice.withCustomMapping() .bind(MockMethodAdvice.Identifier.class, identifier) .to(MockMethodAdvice.ForEquals.class)); - Method getModule, canRead, redefineModule; - try { - getModule = Class.class.getMethod("getModule"); - canRead = getModule.getReturnType().getMethod("canRead", getModule.getReturnType()); - redefineModule = Instrumentation.class.getMethod("redefineModule", - getModule.getReturnType(), Set.class, Map.class, Map.class, Set.class, Map.class); - } catch (Exception ignored) { - getModule = null; - canRead = null; - redefineModule = null; - } - this.getModule = getModule; - this.canRead = canRead; - this.redefineModule = redefineModule; MockMethodDispatcher.set(identifier, new MockMethodAdvice(mocks, identifier)); instrumentation.addTransformer(this, true); } @@ -170,7 +158,6 @@ public class InlineBytecodeGenerator implements BytecodeGenerator, ClassFileTran } while (type != null); if (!types.isEmpty()) { try { - assureCanReadMockito(types); instrumentation.retransformClasses(types.toArray(new Class<?>[types.size()])); Throwable throwable = lastException; if (throwable != null) { @@ -191,32 +178,6 @@ public class InlineBytecodeGenerator implements BytecodeGenerator, ClassFileTran } } - private void assureCanReadMockito(Set<Class<?>> types) { - if (redefineModule == null) { - return; - } - Set<Object> modules = new HashSet<Object>(); - try { - Object target = getModule.invoke(Class.forName("org.mockito.internal.creation.bytebuddy.inject.MockMethodDispatcher", false, null)); - for (Class<?> type : types) { - Object module = getModule.invoke(type); - if (!modules.contains(module) && !(Boolean) canRead.invoke(module, target)) { - modules.add(module); - } - } - for (Object module : modules) { - redefineModule.invoke(instrumentation, module, Collections.singleton(target), - Collections.emptyMap(), Collections.emptyMap(), Collections.emptySet(), Collections.emptyMap()); - } - } catch (Exception e) { - throw new IllegalStateException(join("Could not adjust module graph to make the mock instance dispatcher visible to some classes", - "", - "At least one of those modules: " + modules + " is not reading the unnamed module of the bootstrap loader", - "Without such a read edge, the classes that are redefined to become mocks cannot access the mock dispatcher.", - "To circumvent this, Mockito attempted to add a read edge to this module what failed for an unexpected reason"), e); - } - } - private <T> void checkSupportedCombination(boolean subclassingRequired, MockFeatures<T> features) { if (subclassingRequired && !features.mockedType.isArray() diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodAdvice.java b/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodAdvice.java index 828b848..f39a1a2 100644 --- a/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodAdvice.java +++ b/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodAdvice.java @@ -12,7 +12,6 @@ import net.bytebuddy.implementation.bind.annotation.Argument; import net.bytebuddy.implementation.bind.annotation.This; import net.bytebuddy.implementation.bytecode.assign.Assigner; import org.mockito.exceptions.base.MockitoException; -import org.mockito.internal.creation.bytebuddy.inject.MockMethodDispatcher; import org.mockito.internal.debugging.LocationImpl; import org.mockito.internal.exceptions.stacktrace.ConditionalStackTraceFilter; import org.mockito.internal.invocation.RealMethod; @@ -36,7 +35,7 @@ import java.util.concurrent.Callable; public class MockMethodAdvice extends MockMethodDispatcher { - private final WeakConcurrentMap<Object, MockMethodInterceptor> interceptors; + final WeakConcurrentMap<Object, MockMethodInterceptor> interceptors; private final String identifier; diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodInterceptor.java b/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodInterceptor.java index e57a82e..9066927 100644 --- a/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodInterceptor.java +++ b/src/main/java/org/mockito/internal/creation/bytebuddy/MockMethodInterceptor.java @@ -46,11 +46,13 @@ public class MockMethodInterceptor implements Serializable { Method invokedMethod, Object[] arguments, RealMethod realMethod) throws Throwable { - return doIntercept(mock, - invokedMethod, - arguments, - realMethod, - new LocationImpl()); + return doIntercept( + mock, + invokedMethod, + arguments, + realMethod, + new LocationImpl() + ); } Object doIntercept(Object mock, @@ -106,11 +108,11 @@ public class MockMethodInterceptor implements Serializable { return superCall.call(); } return interceptor.doIntercept( - mock, - invokedMethod, - arguments, - new RealMethod.FromCallable(superCall) - ); + mock, + invokedMethod, + arguments, + new RealMethod.FromCallable(superCall) + ); } @SuppressWarnings("unused") @@ -124,11 +126,11 @@ public class MockMethodInterceptor implements Serializable { return stubValue; } return interceptor.doIntercept( - mock, - invokedMethod, - arguments, - RealMethod.IsIllegal.INSTANCE - ); + mock, + invokedMethod, + arguments, + RealMethod.IsIllegal.INSTANCE + ); } } } diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/ModuleHandler.java b/src/main/java/org/mockito/internal/creation/bytebuddy/ModuleHandler.java deleted file mode 100644 index 5be0b95..0000000 --- a/src/main/java/org/mockito/internal/creation/bytebuddy/ModuleHandler.java +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (c) 2016 Mockito contributors - * This program is made available under the terms of the MIT License. - */ -package org.mockito.internal.creation.bytebuddy; - -import net.bytebuddy.ByteBuddy; -import net.bytebuddy.description.modifier.Ownership; -import net.bytebuddy.description.modifier.Visibility; -import net.bytebuddy.dynamic.scaffold.subclass.ConstructorStrategy; -import net.bytebuddy.implementation.Implementation; -import net.bytebuddy.implementation.MethodCall; -import net.bytebuddy.implementation.StubMethod; -import org.mockito.codegen.InjectionBase; -import org.mockito.exceptions.base.MockitoException; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.Random; - -import static net.bytebuddy.matcher.ElementMatchers.isTypeInitializer; -import static org.mockito.internal.util.StringUtil.join; - -abstract class ModuleHandler { - - abstract boolean isOpened(Class<?> source, Class<?> target); - - abstract boolean canRead(Class<?> source, Class<?> target); - - abstract boolean isExported(Class<?> source); - - abstract boolean isExported(Class<?> source, Class<?> target); - - abstract Class<?> injectionBase(ClassLoader classLoader, String tyoeName); - - abstract void adjustModuleGraph(Class<?> source, Class<?> target, boolean export, boolean read); - - static ModuleHandler make(ByteBuddy byteBuddy, SubclassLoader loader, Random random) { - try { - return new ModuleSystemFound( - byteBuddy, loader, random - ); - } catch (Exception ignored) { - return new NoModuleSystemFound(); - } - } - - private static class ModuleSystemFound extends ModuleHandler { - - private final ByteBuddy byteBuddy; - private final SubclassLoader loader; - private final Random random; - - private final int injectonBaseSuffix; - - private final Method getModule, isOpen, isExported, isExportedUnqualified, canRead, addExports, addReads, addOpens, forName; - - private ModuleSystemFound(ByteBuddy byteBuddy, SubclassLoader loader, Random random) throws Exception { - this.byteBuddy = byteBuddy; - this.loader = loader; - this.random = random; - injectonBaseSuffix = Math.abs(random.nextInt()); - Class<?> moduleType = Class.forName("java.lang.Module"); - getModule = Class.class.getMethod("getModule"); - isOpen = moduleType.getMethod("isOpen", String.class, moduleType); - isExported = moduleType.getMethod("isExported", String.class, moduleType); - isExportedUnqualified = moduleType.getMethod("isExported", String.class); - canRead = moduleType.getMethod("canRead", moduleType); - addExports = moduleType.getMethod("addExports", String.class, moduleType); - addReads = moduleType.getMethod("addReads", moduleType); - addOpens = moduleType.getMethod("addOpens", String.class, moduleType); - forName = Class.class.getMethod("forName", String.class); - } - - @Override - boolean isOpened(Class<?> source, Class<?> target) { - if (source.getPackage() == null) { - return true; - } - return (Boolean) invoke(isOpen, invoke(getModule, source), source.getPackage().getName(), invoke(getModule, target)); - } - - @Override - boolean canRead(Class<?> source, Class<?> target) { - return (Boolean) invoke(canRead, invoke(getModule, source), invoke(getModule, target)); - } - - @Override - boolean isExported(Class<?> source) { - if (source.getPackage() == null) { - return true; - } - return (Boolean) invoke(isExportedUnqualified, invoke(getModule, source), source.getPackage().getName()); - } - - @Override - boolean isExported(Class<?> source, Class<?> target) { - if (source.getPackage() == null) { - return true; - } - return (Boolean) invoke(isExported, invoke(getModule, source), source.getPackage().getName(), invoke(getModule, target)); - } - - @Override - Class<?> injectionBase(ClassLoader classLoader, String typeName) { - String packageName = typeName.substring(0, typeName.lastIndexOf('.')); - if (classLoader == InjectionBase.class.getClassLoader() && InjectionBase.class.getPackage().getName().equals(packageName)) { - return InjectionBase.class; - } else { - synchronized (this) { - String name; - int suffix = injectonBaseSuffix; - do { - name = packageName + "." + InjectionBase.class.getSimpleName() + "$" + suffix++; - try { - Class<?> type = Class.forName(name, false, classLoader); - // The injected type must be defined in the class loader that is target of the injection. Otherwise, - // the class's unnamed module would differ from the intended module. To avoid conflicts, we increment - // the suffix until we hit a class with a known name and generate one if it does not exist. - if (type.getClassLoader() == classLoader) { - return type; - } - } catch (ClassNotFoundException ignored) { - break; - } - } while (true); - return byteBuddy.subclass(Object.class, ConstructorStrategy.Default.NO_CONSTRUCTORS) - .name(name) - .make() - .load(classLoader, loader.resolveStrategy(InjectionBase.class, classLoader, false)) - .getLoaded(); - } - } - } - - @Override - void adjustModuleGraph(Class<?> source, Class<?> target, boolean export, boolean read) { - boolean needsExport = export && !isExported(source, target); - boolean needsRead = read && !canRead(source, target); - if (!needsExport && !needsRead) { - return; - } - ClassLoader classLoader = source.getClassLoader(); - if (classLoader == null) { - throw new MockitoException(join("Cannot adjust module graph for modules in the bootstrap loader", - "", - source + " is declared by the bootstrap loader and cannot be adjusted", - "Requires package export to " + target + ": " + needsExport, - "Requires adjusted reading of " + target + ": " + needsRead)); - } - boolean targetVisible = classLoader == target.getClassLoader(); - while (!targetVisible && classLoader != null) { - classLoader = classLoader.getParent(); - targetVisible = classLoader == target.getClassLoader(); - } - MethodCall targetLookup; - Implementation.Composable implementation; - if (targetVisible) { - targetLookup = MethodCall.invoke(getModule).onMethodCall(MethodCall.invoke(forName).with(target.getName())); - implementation = StubMethod.INSTANCE; - } else { - Class<?> intermediate; - Field field; - try { - intermediate = byteBuddy.subclass(Object.class, ConstructorStrategy.Default.NO_CONSTRUCTORS) - .name(String.format("%s$%d", "org.mockito.codegen.MockitoTypeCarrier", Math.abs(random.nextInt()))) - .defineField("mockitoType", Class.class, Visibility.PUBLIC, Ownership.STATIC) - .make() - .load(source.getClassLoader(), loader.resolveStrategy(source, source.getClassLoader(), false)) - .getLoaded(); - field = intermediate.getField("mockitoType"); - field.set(null, target); - } catch (Exception e) { - throw new MockitoException(join("Could not create a carrier for making the Mockito type visible to " + source, - "", - "This is required to adjust the module graph to enable mock creation"), e); - } - targetLookup = MethodCall.invoke(getModule).onField(field); - implementation = MethodCall.invoke(getModule).onMethodCall(MethodCall.invoke(forName).with(intermediate.getName())); - } - MethodCall sourceLookup = MethodCall.invoke(getModule).onMethodCall(MethodCall.invoke(forName).with(source.getName())); - if (needsExport) { - implementation = implementation.andThen(MethodCall.invoke(addExports) - .onMethodCall(sourceLookup) - .with(target.getPackage().getName()) - .withMethodCall(targetLookup)); - } - if (needsRead) { - implementation = implementation.andThen(MethodCall.invoke(addReads) - .onMethodCall(sourceLookup) - .withMethodCall(targetLookup)); - } - try { - Class.forName(byteBuddy.subclass(Object.class) - .name(String.format("%s$%s$%d", source.getName(), "MockitoModuleProbe", Math.abs(random.nextInt()))) - .invokable(isTypeInitializer()).intercept(implementation) - .make() - .load(source.getClassLoader(), loader.resolveStrategy(source, source.getClassLoader(), false)) - .getLoaded() - .getName(), true, source.getClassLoader()); - } catch (Exception e) { - throw new MockitoException(join("Could not force module adjustment of the module of " + source, - "", - "This is required to adjust the module graph to enable mock creation"), e); - } - } - - private static Object invoke(Method method, Object target, Object... args) { - try { - return method.invoke(target, args); - } catch (Exception e) { - throw new MockitoException(join("Could not invoke " + method + " using reflection", - "", - "Mockito attempted to interact with the Java module system but an unexpected method behavior was encountered"), e); - } - } - } - - private static class NoModuleSystemFound extends ModuleHandler { - - @Override - boolean isOpened(Class<?> source, Class<?> target) { - return true; - } - - @Override - boolean canRead(Class<?> source, Class<?> target) { - return true; - } - - @Override - boolean isExported(Class<?> source) { - return true; - } - - @Override - boolean isExported(Class<?> source, Class<?> target) { - return true; - } - - @Override - Class<?> injectionBase(ClassLoader classLoader, String tyoeName) { - return InjectionBase.class; - } - - @Override - void adjustModuleGraph(Class<?> source, Class<?> target, boolean export, boolean read) { - // empty - } - } -} 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 093978d..b659c73 100644 --- a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassBytecodeGenerator.java +++ b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassBytecodeGenerator.java @@ -15,7 +15,6 @@ import net.bytebuddy.implementation.FieldAccessor; import net.bytebuddy.implementation.Implementation; import net.bytebuddy.implementation.attribute.MethodAttributeAppender; import net.bytebuddy.matcher.ElementMatcher; -import org.mockito.codegen.InjectionBase; import org.mockito.exceptions.base.MockitoException; import org.mockito.internal.creation.bytebuddy.ByteBuddyCrossClassLoaderSerializationSupport.CrossClassLoaderSerializableMock; import org.mockito.internal.creation.bytebuddy.MockMethodInterceptor.DispatcherDefaultingToRealMethod; @@ -27,9 +26,6 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Modifier; import java.lang.reflect.Type; import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.LinkedList; import java.util.Random; import static java.lang.Thread.currentThread; @@ -45,9 +41,10 @@ class SubclassBytecodeGenerator implements BytecodeGenerator { private static final String CODEGEN_PACKAGE = "org.mockito.codegen."; private final SubclassLoader loader; - private final ModuleHandler handler; + private final ByteBuddy byteBuddy; private final Random random; + private final Implementation readReplace; private final ElementMatcher<? super MethodDescription> matcher; @@ -74,128 +71,95 @@ class SubclassBytecodeGenerator implements BytecodeGenerator { this.matcher = matcher; byteBuddy = new ByteBuddy().with(TypeValidation.DISABLED); random = new Random(); - handler = ModuleHandler.make(byteBuddy, loader, random); } @Override public <T> Class<? extends T> mockClass(MockFeatures<T> features) { - ClassLoader classLoader = new MultipleParentClassLoader.Builder() - .appendMostSpecific(getAllTypes(features.mockedType)) - .appendMostSpecific(features.interfaces) - .appendMostSpecific(currentThread().getContextClassLoader()) - .appendMostSpecific(MockAccess.class) - .build(); - - // If Mockito does not need to create a new class loader and if a mock is not based on a JDK type, we attempt - // to define the mock class in the user runtime package to allow for mocking package private types and methods. - // This also requires that we are able to access the package of the mocked class either by override or explicit - // privilege given by the target package being opened to Mockito. - boolean localMock = classLoader == features.mockedType.getClassLoader() - && features.serializableMode != SerializableMode.ACROSS_CLASSLOADERS - && !isComingFromJDK(features.mockedType) - && (loader.isDisrespectingOpenness() || handler.isOpened(features.mockedType, MockAccess.class)); - String typeName; - if (localMock || loader instanceof MultipleParentClassLoader && !isComingFromJDK(features.mockedType)) { - typeName = features.mockedType.getName(); - } else { - typeName = InjectionBase.class.getPackage().getName() + "." + features.mockedType.getSimpleName(); - } - String name = String.format("%s$%s$%d", typeName, "MockitoMock", Math.abs(random.nextInt())); - - if (localMock) { - handler.adjustModuleGraph(features.mockedType, MockAccess.class, false, true); - for (Class<?> iFace : features.interfaces) { - handler.adjustModuleGraph(iFace, features.mockedType, true, false); - handler.adjustModuleGraph(features.mockedType, iFace, false, true); - } - } else { - boolean exported = handler.isExported(features.mockedType); - Iterator<Class<?>> it = features.interfaces.iterator(); - while (exported && it.hasNext()) { - exported = handler.isExported(it.next()); - } - // We check if all mocked types are exported without qualification to avoid generating a hook type. - // unless this is necessary. We expect this to be the case for most mocked types what makes this a - // worthy performance optimization. - if (exported) { - assertVisibility(features.mockedType); - for (Class<?> iFace : features.interfaces) { - assertVisibility(iFace); - } - } else { - Class<?> hook = handler.injectionBase(classLoader, typeName); - assertVisibility(features.mockedType); - handler.adjustModuleGraph(features.mockedType, hook, true, false); - for (Class<?> iFace : features.interfaces) { - assertVisibility(iFace); - handler.adjustModuleGraph(iFace, hook, true, false); - } - } - } - - DynamicType.Builder<T> builder = byteBuddy.subclass(features.mockedType) - .name(name) - .ignoreAlso(isGroovyMethod()) - .annotateType(features.stripAnnotations - ? new Annotation[0] - : features.mockedType.getAnnotations()) - .implement(new ArrayList<Type>(features.interfaces)) - .method(matcher) - .intercept(dispatcher) - .transform(withModifiers(SynchronizationState.PLAIN)) - .attribute(features.stripAnnotations - ? MethodAttributeAppender.NoOp.INSTANCE - : INCLUDING_RECEIVER) - .method(isHashCode()) - .intercept(hashCode) - .method(isEquals()) - .intercept(equals) - .serialVersionUid(42L) - .defineField("mockitoInterceptor", MockMethodInterceptor.class, PRIVATE) - .implement(MockAccess.class) - .intercept(FieldAccessor.ofBeanProperty()); + String name = nameFor(features.mockedType); + DynamicType.Builder<T> builder = + byteBuddy.subclass(features.mockedType) + .name(name) + .ignoreAlso(isGroovyMethod()) + .annotateType(features.stripAnnotations + ? new Annotation[0] + : features.mockedType.getAnnotations()) + .implement(new ArrayList<Type>(features.interfaces)) + .method(matcher) + .intercept(dispatcher) + .transform(withModifiers(SynchronizationState.PLAIN)) + .attribute(features.stripAnnotations + ? MethodAttributeAppender.NoOp.INSTANCE + : INCLUDING_RECEIVER) + .method(isHashCode()) + .intercept(hashCode) + .method(isEquals()) + .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(writeReplace); + .intercept(writeReplace); } if (readReplace != null) { builder = builder.defineMethod("readObject", void.class, Visibility.PRIVATE) - .withParameters(ObjectInputStream.class) - .throwing(ClassNotFoundException.class, IOException.class) - .intercept(readReplace); + .withParameters(ObjectInputStream.class) + .throwing(ClassNotFoundException.class, IOException.class) + .intercept(readReplace); } - if (name.startsWith(CODEGEN_PACKAGE) || classLoader instanceof MultipleParentClassLoader) { + ClassLoader classLoader = new MultipleParentClassLoader.Builder() + .append(features.mockedType) + .append(features.interfaces) + .append(currentThread().getContextClassLoader()) + .append(MockAccess.class, DispatcherDefaultingToRealMethod.class) + .append(MockMethodInterceptor.class, + MockMethodInterceptor.ForHashCode.class, + MockMethodInterceptor.ForEquals.class).build(MockMethodInterceptor.class.getClassLoader()); + if (classLoader != features.mockedType.getClassLoader()) { + assertVisibility(features.mockedType); + for (Class<?> iFace : features.interfaces) { + assertVisibility(iFace); + } builder = builder.ignoreAlso(isPackagePrivate() .or(returns(isPackagePrivate())) .or(hasParameters(whereAny(hasType(isPackagePrivate()))))); } return builder.make() - .load(classLoader, loader.resolveStrategy(features.mockedType, classLoader, localMock)) - .getLoaded(); - } - - private <T> Collection<Class<? super T>> getAllTypes(Class<T> type) { - Collection<Class<? super T>> supertypes = new LinkedList<Class<? super T>>(); - supertypes.add(type); - Class<? super T> superType = type; - while (superType != null) { - supertypes.add(superType); - superType = superType.getSuperclass(); - } - return supertypes; + .load(classLoader, loader.resolveStrategy(features.mockedType, classLoader, name.startsWith(CODEGEN_PACKAGE))) + .getLoaded(); } private static ElementMatcher<MethodDescription> isGroovyMethod() { return isDeclaredBy(named("groovy.lang.GroovyObjectSupport")); } + // TODO inspect naming strategy (for OSGI, signed package, java.* (and bootstrap classes), etc...) + private String nameFor(Class<?> type) { + String typeName = type.getName(); + if (isComingFromJDK(type) + || isComingFromSignedJar(type) + || isComingFromSealedPackage(type)) { + typeName = CODEGEN_PACKAGE + type.getSimpleName(); + } + return String.format("%s$%s$%d", typeName, "MockitoMock", Math.abs(random.nextInt())); + } + private boolean isComingFromJDK(Class<?> type) { // Comes from the manifest entry : // Implementation-Title: Java Runtime Environment // This entry is not necessarily present in every jar of the JDK return type.getPackage() != null && "Java Runtime Environment".equalsIgnoreCase(type.getPackage().getImplementationTitle()) - || type.getName().startsWith("java.") - || type.getName().startsWith("javax."); + || type.getName().startsWith("java.") + || type.getName().startsWith("javax."); + } + + private boolean isComingFromSealedPackage(Class<?> type) { + return type.getPackage() != null && type.getPackage().isSealed(); + } + + private boolean isComingFromSignedJar(Class<?> type) { + return type.getSigners() != null; } private static void assertVisibility(Class<?> type) { 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 89b0a30..454dd8e 100644 --- a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassInjectionLoader.java +++ b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassInjectionLoader.java @@ -25,7 +25,7 @@ class SubclassInjectionLoader implements SubclassLoader { private final SubclassLoader loader; SubclassInjectionLoader() { - if (!Boolean.getBoolean("org.mockito.internal.noUnsafeInjection") && ClassInjector.UsingReflection.isAvailable()) { + if (!Boolean.getBoolean("org.mockito.internal.simulateJava11") && ClassInjector.UsingReflection.isAvailable()) { this.loader = new WithReflection(); } else if (ClassInjector.UsingLookup.isAvailable()) { this.loader = tryLookup(); @@ -49,13 +49,8 @@ class SubclassInjectionLoader implements SubclassLoader { private static class WithReflection implements SubclassLoader { @Override - public boolean isDisrespectingOpenness() { - return true; - } - - @Override - public ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean localMock) { - return ClassLoadingStrategy.Default.INJECTION.with(localMock ? mockedType.getProtectionDomain() : InjectionBase.class.getProtectionDomain()); + public ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean codegen) { + return ClassLoadingStrategy.Default.INJECTION.with(codegen ? InjectionBase.class.getProtectionDomain() : mockedType.getProtectionDomain()); } } @@ -74,13 +69,12 @@ class SubclassInjectionLoader implements SubclassLoader { } @Override - public boolean isDisrespectingOpenness() { - return false; - } - - @Override - public ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean localMock) { - if (localMock) { + 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 { @@ -102,21 +96,12 @@ class SubclassInjectionLoader implements SubclassLoader { exception )); } - } else if (classLoader == InjectionBase.class.getClassLoader()) { - return ClassLoadingStrategy.UsingLookup.of(codegenLookup); - } else { - return ClassLoadingStrategy.Default.WRAPPER.with(mockedType.getProtectionDomain()); } } } @Override - public boolean isDisrespectingOpenness() { - return loader.isDisrespectingOpenness(); - } - - @Override - public ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean localMock) { - return loader.resolveStrategy(mockedType, classLoader, localMock); + 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 011504e..194c282 100644 --- a/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassLoader.java +++ b/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassLoader.java @@ -12,19 +12,12 @@ import net.bytebuddy.dynamic.loading.ClassLoadingStrategy; public interface SubclassLoader { /** - * Checks if this loader does not require a module to be open. - * - * @return {@code true} if this loader is not constraint to a target module being opened for loading a class. - */ - boolean isDisrespectingOpenness(); - - /** * Resolves a class loading strategy. * * @param mockedType The type being mocked. * @param classLoader The class loader being used. - * @param localMock {@code true} if the mock is loaded within the runtime package of the mocked type. + * @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 localMock); + ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> mockedType, ClassLoader classLoader, boolean codegen); } diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/inject/MockMethodDispatcher.java b/src/main/java/org/mockito/internal/creation/bytebuddy/inject/MockMethodDispatcher.java deleted file mode 100644 index 12e30db..0000000 --- a/src/main/java/org/mockito/internal/creation/bytebuddy/inject/MockMethodDispatcher.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2016 Mockito contributors - * This program is made available under the terms of the MIT License. - */ -package org.mockito.internal.creation.bytebuddy.inject; - -import java.lang.reflect.Method; -import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -public abstract class MockMethodDispatcher { - - private static final ConcurrentMap<String, MockMethodDispatcher> INSTANCE = new ConcurrentHashMap<String, MockMethodDispatcher>(); - - public static MockMethodDispatcher get(String identifier, Object mock) { - if (mock == INSTANCE) { // Avoid endless loop if ConcurrentHashMap was redefined to check for being a mock. - return null; - } else { - return INSTANCE.get(identifier); - } - } - - public static void set(String identifier, MockMethodDispatcher dispatcher) { - INSTANCE.putIfAbsent(identifier, dispatcher); - } - - public abstract Callable<?> handle(Object instance, Method origin, Object[] arguments) throws Throwable; - - public abstract boolean isMock(Object instance); - - public abstract boolean isMocked(Object instance); - - public abstract boolean isOverridden(Object instance, Method origin); -} diff --git a/src/main/java/org/mockito/internal/creation/bytebuddy/inject/package-info.java b/src/main/java/org/mockito/internal/creation/bytebuddy/inject/package-info.java deleted file mode 100644 index 5abed05..0000000 --- a/src/main/java/org/mockito/internal/creation/bytebuddy/inject/package-info.java +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright (c) 2007 Mockito contributors - * This program is made available under the terms of the MIT License. - */ - -/** - * Internal classes, not to be used by clients. Intended for injection into the bootstrap class loader. - * - * Subject to change at any time without notice. - */ -package org.mockito.internal.creation.bytebuddy.inject; diff --git a/src/main/java/org/mockito/internal/creation/settings/CreationSettings.java b/src/main/java/org/mockito/internal/creation/settings/CreationSettings.java index 3b45592..03afd80 100644 --- a/src/main/java/org/mockito/internal/creation/settings/CreationSettings.java +++ b/src/main/java/org/mockito/internal/creation/settings/CreationSettings.java @@ -4,8 +4,8 @@ */ package org.mockito.internal.creation.settings; +import org.mockito.internal.listeners.StubbingLookupListener; import org.mockito.listeners.InvocationListener; -import org.mockito.listeners.StubbingLookupListener; import org.mockito.listeners.VerificationStartedListener; import org.mockito.mock.MockCreationSettings; import org.mockito.mock.MockName; @@ -18,7 +18,6 @@ import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; -import java.util.concurrent.CopyOnWriteArrayList; public class CreationSettings<T> implements MockCreationSettings<T>, Serializable { private static final long serialVersionUID = -6789800638070123629L; @@ -31,11 +30,7 @@ public class CreationSettings<T> implements MockCreationSettings<T>, Serializabl protected MockName mockName; protected SerializableMode serializableMode = SerializableMode.NONE; protected List<InvocationListener> invocationListeners = new ArrayList<InvocationListener>(); - - //Other listeners in this class may also need concurrency-safe implementation. However, no issue was reported about it. - // If we do it, we need to understand usage patterns and choose the right concurrent implementation. - protected List<StubbingLookupListener> stubbingLookupListeners = new CopyOnWriteArrayList<StubbingLookupListener>(); - + protected final List<StubbingLookupListener> stubbingLookupListeners = new ArrayList<StubbingLookupListener>(); protected List<VerificationStartedListener> verificationStartedListeners = new LinkedList<VerificationStartedListener>(); protected boolean stubOnly; protected boolean stripAnnotations; @@ -48,7 +43,6 @@ public class CreationSettings<T> implements MockCreationSettings<T>, Serializabl @SuppressWarnings("unchecked") public CreationSettings(CreationSettings copy) { - //TODO can we have a reflection test here? We had a couple of bugs here in the past. this.typeToMock = copy.typeToMock; this.extraInterfaces = copy.extraInterfaces; this.name = copy.name; @@ -57,14 +51,12 @@ public class CreationSettings<T> implements MockCreationSettings<T>, Serializabl this.mockName = copy.mockName; this.serializableMode = copy.serializableMode; this.invocationListeners = copy.invocationListeners; - this.stubbingLookupListeners = copy.stubbingLookupListeners; this.verificationStartedListeners = copy.verificationStartedListeners; this.stubOnly = copy.stubOnly; this.useConstructor = copy.isUsingConstructor(); this.outerClassInstance = copy.getOuterClassInstance(); this.constructorArgs = copy.getConstructorArgs(); this.lenient = copy.lenient; - this.stripAnnotations = copy.stripAnnotations; } @Override diff --git a/src/main/java/org/mockito/internal/debugging/LocationImpl.java b/src/main/java/org/mockito/internal/debugging/LocationImpl.java index f1d14a6..8561b62 100644 --- a/src/main/java/org/mockito/internal/debugging/LocationImpl.java +++ b/src/main/java/org/mockito/internal/debugging/LocationImpl.java @@ -16,7 +16,6 @@ public class LocationImpl implements Location, Serializable { private final Throwable stackTraceHolder; private final StackTraceFilter stackTraceFilter; - private final String sourceFile; public LocationImpl() { this(defaultStackTraceFilter); @@ -33,13 +32,6 @@ public class LocationImpl implements Location, Serializable { private LocationImpl(StackTraceFilter stackTraceFilter, Throwable stackTraceHolder) { this.stackTraceFilter = stackTraceFilter; this.stackTraceHolder = stackTraceHolder; - if (stackTraceHolder.getStackTrace() == null || stackTraceHolder.getStackTrace().length == 0) { - //there are corner cases where exception can have a null or empty stack trace - //for example, a custom exception can override getStackTrace() method - this.sourceFile = "<unknown source file>"; - } else { - this.sourceFile = stackTraceFilter.findSourceFile(stackTraceHolder.getStackTrace(), "<unknown source file>"); - } } @Override @@ -51,9 +43,4 @@ public class LocationImpl implements Location, Serializable { } return "-> at " + filtered[0].toString(); } - - @Override - public String getSourceFile() { - return sourceFile; - } } diff --git a/src/main/java/org/mockito/internal/exceptions/Reporter.java b/src/main/java/org/mockito/internal/exceptions/Reporter.java index 1b68fbb..2bc4445 100644 --- a/src/main/java/org/mockito/internal/exceptions/Reporter.java +++ b/src/main/java/org/mockito/internal/exceptions/Reporter.java @@ -26,6 +26,7 @@ import org.mockito.invocation.Invocation; import org.mockito.invocation.InvocationOnMock; import org.mockito.invocation.Location; import org.mockito.listeners.InvocationListener; +import org.mockito.mock.MockName; import org.mockito.mock.SerializableMode; import java.lang.reflect.Field; @@ -83,7 +84,7 @@ public class Reporter { "Hints:", " 1. missing thenReturn()", " 2. you are trying to stub a final method, which is not supported", - " 3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction is completed", + " 3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed", "" )); } @@ -276,10 +277,10 @@ public class Reporter { )); } - public static MockitoException stubPassedToVerify(Object mock) { + public static MockitoException stubPassedToVerify() { return new CannotVerifyStubOnlyMock(join( - "Argument \"" + MockUtil.getMockName(mock) + "\" passed to verify is a stubOnly() mock which cannot be verified.", - "If you intend to verify invocations on this mock, don't use stubOnly() in its MockSettings." + "Argument passed to verify() is a stubOnly() mock, not a full blown mock!", + "If you intend to verify invocations on a mock, don't use stubOnly() in its MockSettings." )); } @@ -436,7 +437,7 @@ public class Reporter { return new NoInteractionsWanted(join( "No interactions wanted here:", new LocationImpl(), - "But found this interaction on mock '" + MockUtil.getMockName(undesired.getMock()) + "':", + "But found this interaction on mock '" + safelyGetMockName(undesired.getMock()) + "':", undesired.getLocation(), scenario )); @@ -446,7 +447,7 @@ public class Reporter { return new VerificationInOrderFailure(join( "No interactions wanted here:", new LocationImpl(), - "But found this interaction on mock '" + MockUtil.getMockName(undesired.getMock()) + "':", + "But found this interaction on mock '" + safelyGetMockName(undesired.getMock()) + "':", undesired.getLocation() )); } @@ -512,7 +513,7 @@ public class Reporter { actualType + " cannot be returned by " + methodName + "()", methodName + "() should return " + expectedType, "", - "The default answer of " + MockUtil.getMockName(mock) + " that was configured on the mock is probably incorrectly implemented.", + "The default answer of " + safelyGetMockName(mock) + " that was configured on the mock is probably incorrectly implemented.", "" )); } @@ -672,7 +673,7 @@ public class Reporter { } public static MockitoException fieldInitialisationThrewException(Field field, Throwable details) { - return new InjectMocksException(join( + return new MockitoException(join( "Cannot instantiate @InjectMocks field named '" + field.getName() + "' of type '" + field.getType() + "'.", "You haven't provided the instance at field declaration so I tried to construct the instance.", "However the constructor or the initialization block threw an exception : " + details.getMessage(), @@ -684,8 +685,8 @@ public class Reporter { return new MockitoException(method + "() does not accept " + parameter + " See the Javadoc."); } - public static MockitoException requiresAtLeastOneListener(String method) { - return new MockitoException(method + "() requires at least one listener"); + public static MockitoException invocationListenersRequiresAtLeastOneListener() { + return new MockitoException("invocationListeners() requires at least one listener"); } public static MockitoException invocationListenerThrewException(InvocationListener listener, Throwable listenerThrowable) { @@ -696,7 +697,7 @@ public class Reporter { public static MockitoException cannotInjectDependency(Field field, Object matchingMock, Exception details) { return new MockitoException(join( - "Mockito couldn't inject mock dependency '" + MockUtil.getMockName(matchingMock) + "' on field ", + "Mockito couldn't inject mock dependency '" + safelyGetMockName(matchingMock) + "' on field ", "'" + field + "'", "whose type '" + field.getDeclaringClass().getCanonicalName() + "' was annotated by @InjectMocks in your test.", "Also I failed because: " + exceptionCauseMessageIfAvailable(details), @@ -739,7 +740,7 @@ public class Reporter { public static MockitoException invalidArgumentPositionRangeAtInvocationTime(InvocationOnMock invocation, boolean willReturnLastParameter, int argumentIndex) { return new MockitoException(join( "Invalid argument index for the current invocation of method : ", - " -> " + MockUtil.getMockName(invocation.getMock()) + "." + invocation.getMethod().getName() + "()", + " -> " + safelyGetMockName(invocation.getMock()) + "." + invocation.getMethod().getName() + "()", "", (willReturnLastParameter ? "Last parameter wanted" : @@ -773,7 +774,7 @@ public class Reporter { return new WrongTypeOfReturnValue(join( "The argument of type '" + actualType.getSimpleName() + "' cannot be returned because the following ", "method should return the type '" + expectedType + "'", - " -> " + MockUtil.getMockName(invocation.getMock()) + "." + invocation.getMethod().getName() + "()", + " -> " + safelyGetMockName(invocation.getMock()) + "." + invocation.getMethod().getName() + "()", "", "The reason for this error can be :", "1. The wanted argument position is incorrect.", @@ -810,7 +811,7 @@ public class Reporter { public static MockitoException delegatedMethodHasWrongReturnType(Method mockMethod, Method delegateMethod, Object mock, Object delegate) { return new MockitoException(join( "Methods called on delegated instance must have compatible return types with the mock.", - "When calling: " + mockMethod + " on mock: " + MockUtil.getMockName(mock), + "When calling: " + mockMethod + " on mock: " + safelyGetMockName(mock), "return type should be: " + mockMethod.getReturnType().getSimpleName() + ", but was: " + delegateMethod.getReturnType().getSimpleName(), "Check that the instance passed to delegatesTo() is of the correct type or contains compatible methods", "(delegate instance had type: " + delegate.getClass().getSimpleName() + ")" @@ -820,7 +821,7 @@ public class Reporter { public static MockitoException delegatedMethodDoesNotExistOnDelegate(Method mockMethod, Object mock, Object delegate) { return new MockitoException(join( "Methods called on mock must exist in delegated instance.", - "When calling: " + mockMethod + " on mock: " + MockUtil.getMockName(mock), + "When calling: " + mockMethod + " on mock: " + safelyGetMockName(mock), "no such method was found.", "Check that the instance passed to delegatesTo() is of the correct type or contains compatible methods", "(delegate instance had type: " + delegate.getClass().getSimpleName() + ")" @@ -848,6 +849,10 @@ public class Reporter { "This may happen with doThrow(Class)|thenThrow(Class) family of methods if passing null parameter.")); } + private static MockName safelyGetMockName(Object mock) { + return MockUtil.getMockName(mock); + } + public static UnnecessaryStubbingException formatUnncessaryStubbingException(Class<?> testClass, Collection<Invocation> unnecessaryStubbings) { StringBuilder stubbings = new StringBuilder(); int count = 1; diff --git a/src/main/java/org/mockito/internal/exceptions/stacktrace/StackTraceFilter.java b/src/main/java/org/mockito/internal/exceptions/stacktrace/StackTraceFilter.java index bf11d4c..e8b0cb0 100644 --- a/src/main/java/org/mockito/internal/exceptions/stacktrace/StackTraceFilter.java +++ b/src/main/java/org/mockito/internal/exceptions/stacktrace/StackTraceFilter.java @@ -37,17 +37,4 @@ public class StackTraceFilter implements Serializable { StackTraceElement[] result = new StackTraceElement[filtered.size()]; return filtered.toArray(result); } - - /** - * Finds the source file of the target stack trace. - * Returns the default value if source file cannot be found. - */ - public String findSourceFile(StackTraceElement[] target, String defaultValue) { - for (StackTraceElement e : target) { - if (CLEANER.isIn(e)) { - return e.getFileName(); - } - } - return defaultValue; - } } diff --git a/src/main/java/org/mockito/internal/framework/DefaultMockitoFramework.java b/src/main/java/org/mockito/internal/framework/DefaultMockitoFramework.java index d92fc28..69a733c 100644 --- a/src/main/java/org/mockito/internal/framework/DefaultMockitoFramework.java +++ b/src/main/java/org/mockito/internal/framework/DefaultMockitoFramework.java @@ -10,8 +10,6 @@ import org.mockito.internal.invocation.DefaultInvocationFactory; import org.mockito.internal.util.Checks; import org.mockito.invocation.InvocationFactory; import org.mockito.listeners.MockitoListener; -import org.mockito.plugins.InlineMockMaker; -import org.mockito.plugins.MockMaker; import org.mockito.plugins.MockitoPlugins; import static org.mockito.internal.progress.ThreadSafeMockingProgress.mockingProgress; @@ -39,25 +37,4 @@ public class DefaultMockitoFramework implements MockitoFramework { public InvocationFactory getInvocationFactory() { return new DefaultInvocationFactory(); } - - private InlineMockMaker getInlineMockMaker() { - MockMaker mockMaker = Plugins.getMockMaker(); - return (mockMaker instanceof InlineMockMaker) ? (InlineMockMaker) mockMaker : null; - } - - @Override - public void clearInlineMocks() { - InlineMockMaker mockMaker = getInlineMockMaker(); - if (mockMaker != null) { - mockMaker.clearAllMocks(); - } - } - - @Override - public void clearInlineMock(Object mock) { - InlineMockMaker mockMaker = getInlineMockMaker(); - if (mockMaker != null) { - mockMaker.clearMock(mock); - } - } } diff --git a/src/main/java/org/mockito/internal/framework/DefaultMockitoSession.java b/src/main/java/org/mockito/internal/framework/DefaultMockitoSession.java index 6483a1c..c900bf7 100644 --- a/src/main/java/org/mockito/internal/framework/DefaultMockitoSession.java +++ b/src/main/java/org/mockito/internal/framework/DefaultMockitoSession.java @@ -11,17 +11,19 @@ import org.mockito.exceptions.misusing.RedundantListenerException; import org.mockito.internal.exceptions.Reporter; import org.mockito.internal.junit.TestFinishedEvent; import org.mockito.internal.junit.UniversalTestListener; -import org.mockito.plugins.MockitoLogger; +import org.mockito.internal.util.MockitoLogger; import org.mockito.quality.Strictness; import java.util.List; public class DefaultMockitoSession implements MockitoSession { + private final List<Object> testClassInstances; private final String name; private final UniversalTestListener listener; public DefaultMockitoSession(List<Object> testClassInstances, String name, Strictness strictness, MockitoLogger logger) { + this.testClassInstances = testClassInstances; this.name = name; listener = new UniversalTestListener(strictness, logger); try { @@ -30,14 +32,8 @@ public class DefaultMockitoSession implements MockitoSession { } catch (RedundantListenerException e) { Reporter.unfinishedMockingSession(); } - try { - for (Object testClassInstance : testClassInstances) { - MockitoAnnotations.initMocks(testClassInstance); - } - } catch (RuntimeException e) { - //clean up in case 'initMocks' fails - listener.setListenerDirty(); - throw e; + for (Object testClassInstance : testClassInstances) { + MockitoAnnotations.initMocks(testClassInstance); } } diff --git a/src/main/java/org/mockito/internal/invocation/InterceptedInvocation.java b/src/main/java/org/mockito/internal/invocation/InterceptedInvocation.java index ec1fcba..b9cf072 100644 --- a/src/main/java/org/mockito/internal/invocation/InterceptedInvocation.java +++ b/src/main/java/org/mockito/internal/invocation/InterceptedInvocation.java @@ -4,7 +4,6 @@ */ package org.mockito.internal.invocation; -import org.mockito.ArgumentMatcher; import org.mockito.internal.invocation.mockref.MockReference; import org.mockito.internal.exceptions.VerificationAwareInvocation; import org.mockito.internal.reporting.PrintSettings; @@ -14,10 +13,8 @@ import org.mockito.invocation.StubInfo; import java.lang.reflect.Method; import java.util.Arrays; -import java.util.List; import static org.mockito.internal.exceptions.Reporter.cannotCallAbstractRealMethod; -import static org.mockito.internal.invocation.ArgumentsProcessor.argumentsToMatchers; public class InterceptedInvocation implements Invocation, VerificationAwareInvocation { @@ -122,28 +119,6 @@ public class InterceptedInvocation implements Invocation, VerificationAwareInvoc return (T) arguments[index]; } - public MockReference<Object> getMockRef() { - return mockRef; - } - - public MockitoMethod getMockitoMethod() { - return mockitoMethod; - } - - public RealMethod getRealMethod() { - return realMethod; - } - - @Override - public List<ArgumentMatcher> getArgumentsAsMatchers() { - return argumentsToMatchers(getArguments()); - } - - @Override - public <T> T getArgument(int index, Class<T> clazz) { - return clazz.cast(arguments[index]); - } - @Override public Object callRealMethod() throws Throwable { if (!realMethod.isInvokable()) { @@ -174,7 +149,7 @@ public class InterceptedInvocation implements Invocation, VerificationAwareInvoc } public String toString() { - return new PrintSettings().print(getArgumentsAsMatchers(), this); + return new PrintSettings().print(ArgumentsProcessor.argumentsToMatchers(getArguments()), this); } public final static RealMethod NO_OP = new RealMethod() { diff --git a/src/main/java/org/mockito/internal/invocation/InvocationMatcher.java b/src/main/java/org/mockito/internal/invocation/InvocationMatcher.java index bc14300..83a28ff 100644 --- a/src/main/java/org/mockito/internal/invocation/InvocationMatcher.java +++ b/src/main/java/org/mockito/internal/invocation/InvocationMatcher.java @@ -5,6 +5,7 @@ package org.mockito.internal.invocation; +import static org.mockito.internal.invocation.ArgumentsProcessor.argumentsToMatchers; import static org.mockito.internal.invocation.MatcherApplicationStrategy.getMatcherApplicationStrategyFor; import static org.mockito.internal.invocation.TypeSafeMatching.matchesTypeSafe; @@ -35,7 +36,7 @@ public class InvocationMatcher implements MatchableInvocation, DescribedInvocati public InvocationMatcher(Invocation invocation, List<ArgumentMatcher> matchers) { this.invocation = invocation; if (matchers.isEmpty()) { - this.matchers = (List) invocation.getArgumentsAsMatchers(); + this.matchers = (List) argumentsToMatchers(invocation.getArguments()); } else { this.matchers = (List) matchers; } diff --git a/src/main/java/org/mockito/internal/junit/DefaultStubbingLookupListener.java b/src/main/java/org/mockito/internal/junit/DefaultStubbingLookupListener.java index b5d2022..4885d63 100644 --- a/src/main/java/org/mockito/internal/junit/DefaultStubbingLookupListener.java +++ b/src/main/java/org/mockito/internal/junit/DefaultStubbingLookupListener.java @@ -5,14 +5,13 @@ package org.mockito.internal.junit; import org.mockito.internal.exceptions.Reporter; +import org.mockito.internal.listeners.StubbingLookupEvent; +import org.mockito.internal.listeners.StubbingLookupListener; import org.mockito.internal.stubbing.UnusedStubbingReporting; import org.mockito.invocation.Invocation; -import org.mockito.listeners.StubbingLookupEvent; -import org.mockito.listeners.StubbingLookupListener; import org.mockito.quality.Strictness; import org.mockito.stubbing.Stubbing; -import java.io.Serializable; import java.util.Collection; import java.util.LinkedList; import java.util.List; @@ -23,9 +22,7 @@ import static org.mockito.internal.stubbing.StrictnessSelector.determineStrictne * Default implementation of stubbing lookup listener. * Fails early if stub called with unexpected arguments, but only if current strictness is set to STRICT_STUBS. */ -class DefaultStubbingLookupListener implements StubbingLookupListener, Serializable { - - private static final long serialVersionUID = -6789800638070123629L; +class DefaultStubbingLookupListener implements StubbingLookupListener { private Strictness currentStrictness; private boolean mismatchesReported; @@ -60,11 +57,8 @@ class DefaultStubbingLookupListener implements StubbingLookupListener, Serializa List<Invocation> matchingStubbings = new LinkedList<Invocation>(); for (Stubbing s : stubbings) { if (UnusedStubbingReporting.shouldBeReported(s) - && s.getInvocation().getMethod().getName().equals(invocation.getMethod().getName()) - //If stubbing and invocation are in the same source file we assume they are in the test code, - // and we don't flag it as mismatch: - && !s.getInvocation().getLocation().getSourceFile().equals(invocation.getLocation().getSourceFile())) { - matchingStubbings.add(s.getInvocation()); + && s.getInvocation().getMethod().getName().equals(invocation.getMethod().getName())) { + matchingStubbings.add(s.getInvocation()); } } return matchingStubbings; diff --git a/src/main/java/org/mockito/internal/junit/ExceptionFactory.java b/src/main/java/org/mockito/internal/junit/ExceptionFactory.java index 5db296e..3664aea 100644 --- a/src/main/java/org/mockito/internal/junit/ExceptionFactory.java +++ b/src/main/java/org/mockito/internal/junit/ExceptionFactory.java @@ -4,58 +4,49 @@ */ package org.mockito.internal.junit; +import junit.framework.ComparisonFailure; import org.mockito.exceptions.verification.ArgumentsAreDifferent; public class ExceptionFactory { + private final static boolean hasJUnit = canLoadJunitClass(); + private ExceptionFactory() { } - private static interface ExceptionFactoryImpl { - AssertionError create(String message, String wanted, String actual); + /** + * If JUnit is used, an AssertionError is returned that extends from JUnit {@link ComparisonFailure} and hence provide a better IDE support as the comparison result is comparable + */ + public static AssertionError createArgumentsAreDifferentException(String message, String wanted, String actual) { + if (hasJUnit) { + return createJUnitArgumentsAreDifferent(message, wanted, actual); + } + return new ArgumentsAreDifferent(message); } - private final static ExceptionFactoryImpl factory; - - static { - ExceptionFactoryImpl theFactory = null; + private static AssertionError createJUnitArgumentsAreDifferent(String message, String wanted, String actual) { + return JUnitArgsAreDifferent.create(message, wanted, actual); + } + private static boolean canLoadJunitClass() { try { - theFactory = new ExceptionFactoryImpl() { - @Override - public AssertionError create(String message, String wanted, String actual) { - return new org.mockito.exceptions.verification.opentest4j.ArgumentsAreDifferent(message, wanted, actual); - } - }; - } catch (Throwable onlyIfOpenTestIsNotAvailable) { - try { - theFactory = new ExceptionFactoryImpl() { - @Override - public AssertionError create(String message, String wanted, String actual) { - return new org.mockito.exceptions.verification.junit.ArgumentsAreDifferent(message, wanted, actual); - } - }; - } catch (Throwable onlyIfJUnitIsNotAvailable) { - } + JUnitArgsAreDifferent.create("message", "wanted", "actual"); + } catch (NoClassDefFoundError onlyIfJUnitIsNotAvailable) { + return false; } - factory = (theFactory == null) ? new ExceptionFactoryImpl() { - @Override - public AssertionError create(String message, String wanted, String actual) { - return new ArgumentsAreDifferent(message, wanted, actual); - } - } : theFactory; + return true; } /** - * Returns an AssertionError that describes the fact that the arguments of an invocation are different. - * If {@link org.opentest4j.AssertionFailedError} is on the class path (used by JUnit 5 and others), - * it returns a class that extends it. Otherwise, if {@link junit.framework.ComparisonFailure} is on the - * class path (shipped with JUnit 3 and 4), it will return a class that extends that. This provides - * better IDE support as the comparison result can be opened in a visual diff. If neither are available, - * it returns an instance of - * {@link org.mockito.exceptions.verification.ArgumentsAreDifferent}. + * Don't inline this class! It allows create the JUnit-ArgumentsAreDifferent exception without the need to use reflection. + * <p> + * If JUnit is not available a call to {@link #create(String, String, String)} will throw a {@link NoClassDefFoundError}. + * The {@link NoClassDefFoundError} will be thrown by the class loader cause the JUnit class {@link ComparisonFailure} + * can't be loaded which is a upper class of ArgumentsAreDifferent. */ - public static AssertionError createArgumentsAreDifferentException(String message, String wanted, String actual) { - return factory.create(message, wanted, actual); + private static class JUnitArgsAreDifferent { + static AssertionError create(String message, String wanted, String actual) { + return new org.mockito.exceptions.verification.junit.ArgumentsAreDifferent(message, wanted, actual); + } } } diff --git a/src/main/java/org/mockito/internal/junit/JUnitRule.java b/src/main/java/org/mockito/internal/junit/JUnitRule.java index 3bd3dac..b825416 100644 --- a/src/main/java/org/mockito/internal/junit/JUnitRule.java +++ b/src/main/java/org/mockito/internal/junit/JUnitRule.java @@ -7,10 +7,9 @@ package org.mockito.internal.junit; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.Statement; import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; import org.mockito.MockitoSession; import org.mockito.internal.session.MockitoSessionLoggerAdapter; -import org.mockito.plugins.MockitoLogger; +import org.mockito.internal.util.MockitoLogger; import org.mockito.quality.Strictness; import org.mockito.junit.MockitoRule; @@ -35,16 +34,12 @@ public class JUnitRule implements MockitoRule { public Statement apply(final Statement base, final FrameworkMethod method, final Object target) { return new Statement() { public void evaluate() throws Throwable { - if (session == null) { - session = Mockito.mockitoSession() - .name(target.getClass().getSimpleName() + "." + method.getName()) - .strictness(strictness) - .logger(new MockitoSessionLoggerAdapter(logger)) - .initMocks(target) - .startMocking(); - } else { - MockitoAnnotations.initMocks(target); - } + session = Mockito.mockitoSession() + .name(target.getClass().getSimpleName() + "." + method.getName()) + .strictness(strictness) + .logger(new MockitoSessionLoggerAdapter(logger)) + .initMocks(target) + .startMocking(); Throwable testFailure = evaluateSafely(base); session.finishMocking(testFailure); if (testFailure != null) { diff --git a/src/main/java/org/mockito/internal/junit/MismatchReportingTestListener.java b/src/main/java/org/mockito/internal/junit/MismatchReportingTestListener.java index d705396..26d4e4e 100644 --- a/src/main/java/org/mockito/internal/junit/MismatchReportingTestListener.java +++ b/src/main/java/org/mockito/internal/junit/MismatchReportingTestListener.java @@ -4,7 +4,7 @@ */ package org.mockito.internal.junit; -import org.mockito.plugins.MockitoLogger; +import org.mockito.internal.util.MockitoLogger; import org.mockito.mock.MockCreationSettings; import java.util.Collection; diff --git a/src/main/java/org/mockito/internal/junit/StrictStubsRunnerTestListener.java b/src/main/java/org/mockito/internal/junit/StrictStubsRunnerTestListener.java index d23431b..9e60c31 100644 --- a/src/main/java/org/mockito/internal/junit/StrictStubsRunnerTestListener.java +++ b/src/main/java/org/mockito/internal/junit/StrictStubsRunnerTestListener.java @@ -4,6 +4,7 @@ */ package org.mockito.internal.junit; +import org.mockito.internal.creation.settings.CreationSettings; import org.mockito.mock.MockCreationSettings; import org.mockito.quality.Strictness; @@ -21,8 +22,8 @@ public class StrictStubsRunnerTestListener implements MockitoTestListener { public void onMockCreated(Object mock, MockCreationSettings settings) { //It is not ideal that we modify the state of MockCreationSettings object //MockCreationSettings is intended to be an immutable view of the creation settings - //However, we our previous listeners work this way and it hasn't backfired. - //Since it is simple and pragmatic, we'll keep it for now. - settings.getStubbingLookupListeners().add(stubbingLookupListener); + //In future, we should start passing MockSettings object to the creation listener + //TODO #793 - when completed, we should be able to get rid of the CreationSettings casting below + ((CreationSettings) settings).getStubbingLookupListeners().add(stubbingLookupListener); } } diff --git a/src/main/java/org/mockito/internal/junit/StubbingArgMismatches.java b/src/main/java/org/mockito/internal/junit/StubbingArgMismatches.java index f125f60..3d6342c 100644 --- a/src/main/java/org/mockito/internal/junit/StubbingArgMismatches.java +++ b/src/main/java/org/mockito/internal/junit/StubbingArgMismatches.java @@ -4,7 +4,7 @@ */ package org.mockito.internal.junit; -import org.mockito.plugins.MockitoLogger; +import org.mockito.internal.util.MockitoLogger; import org.mockito.invocation.Invocation; import java.util.LinkedHashMap; diff --git a/src/main/java/org/mockito/internal/junit/UniversalTestListener.java b/src/main/java/org/mockito/internal/junit/UniversalTestListener.java index d681823..66c9dee 100644 --- a/src/main/java/org/mockito/internal/junit/UniversalTestListener.java +++ b/src/main/java/org/mockito/internal/junit/UniversalTestListener.java @@ -5,8 +5,7 @@ package org.mockito.internal.junit; import org.mockito.internal.creation.settings.CreationSettings; -import org.mockito.internal.listeners.AutoCleanableListener; -import org.mockito.plugins.MockitoLogger; +import org.mockito.internal.util.MockitoLogger; import org.mockito.mock.MockCreationSettings; import org.mockito.quality.Strictness; @@ -19,14 +18,13 @@ import java.util.Map; * Will come handy when we offer tweaking strictness at the method level with annotation. * Should be relatively easy to improve and offer tweaking strictness per mock. */ -public class UniversalTestListener implements MockitoTestListener, AutoCleanableListener { +public class UniversalTestListener implements MockitoTestListener { private Strictness currentStrictness; private final MockitoLogger logger; private Map<Object, MockCreationSettings> mocks = new IdentityHashMap<Object, MockCreationSettings>(); private DefaultStubbingLookupListener stubbingLookupListener; - private boolean listenerDirty; public UniversalTestListener(Strictness initialStrictness, MockitoLogger logger) { this.currentStrictness = initialStrictness; @@ -87,19 +85,4 @@ public class UniversalTestListener implements MockitoTestListener, AutoCleanable this.currentStrictness = strictness; this.stubbingLookupListener.setCurrentStrictness(strictness); } - - /** - * See {@link AutoCleanableListener#isListenerDirty()} - */ - @Override - public boolean isListenerDirty() { - return listenerDirty; - } - - /** - * Marks listener as dirty, scheduled for cleanup when the next session starts - */ - public void setListenerDirty() { - this.listenerDirty = true; - } } diff --git a/src/main/java/org/mockito/internal/junit/UnusedStubbings.java b/src/main/java/org/mockito/internal/junit/UnusedStubbings.java index d45b13d..3505d2c 100644 --- a/src/main/java/org/mockito/internal/junit/UnusedStubbings.java +++ b/src/main/java/org/mockito/internal/junit/UnusedStubbings.java @@ -5,7 +5,7 @@ package org.mockito.internal.junit; import org.mockito.internal.exceptions.Reporter; -import org.mockito.plugins.MockitoLogger; +import org.mockito.internal.util.MockitoLogger; import org.mockito.invocation.Invocation; import org.mockito.stubbing.Stubbing; diff --git a/src/main/java/org/mockito/internal/junit/VerificationCollectorImpl.java b/src/main/java/org/mockito/internal/junit/VerificationCollectorImpl.java index e54d478..7c19d35 100644 --- a/src/main/java/org/mockito/internal/junit/VerificationCollectorImpl.java +++ b/src/main/java/org/mockito/internal/junit/VerificationCollectorImpl.java @@ -75,7 +75,7 @@ public class VerificationCollectorImpl implements VerificationCollector { this.numberOfFailures++; this.builder.append('\n') .append(this.numberOfFailures).append(". ") - .append(message.trim()).append('\n'); + .append(message.substring(1, message.length())); } private class VerificationWrapper implements VerificationMode { @@ -89,7 +89,7 @@ public class VerificationCollectorImpl implements VerificationCollector { public void verify(VerificationData data) { try { this.delegate.verify(data); - } catch (AssertionError error) { + } catch (MockitoAssertionError error) { VerificationCollectorImpl.this.append(error.getMessage()); } } diff --git a/src/main/java/org/mockito/internal/listeners/AutoCleanableListener.java b/src/main/java/org/mockito/internal/listeners/AutoCleanableListener.java deleted file mode 100644 index cfd2a53..0000000 --- a/src/main/java/org/mockito/internal/listeners/AutoCleanableListener.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2018 Mockito contributors - * This program is made available under the terms of the MIT License. - */ -package org.mockito.internal.listeners; - -/** - * Listener that is automatically cleaned up (removed from the the global list of subscribers). - * For now, we don't intend to make this interface public. - */ -public interface AutoCleanableListener { - - /** - * Indicates that the listener is dirty and should be removed from the subscribers - */ - boolean isListenerDirty(); -} diff --git a/src/main/java/org/mockito/internal/listeners/StubbingLookupNotifier.java b/src/main/java/org/mockito/internal/listeners/StubbingLookupNotifier.java index a0de0c3..3e55001 100644 --- a/src/main/java/org/mockito/internal/listeners/StubbingLookupNotifier.java +++ b/src/main/java/org/mockito/internal/listeners/StubbingLookupNotifier.java @@ -6,8 +6,6 @@ package org.mockito.internal.listeners; import org.mockito.internal.creation.settings.CreationSettings; import org.mockito.invocation.Invocation; -import org.mockito.listeners.StubbingLookupEvent; -import org.mockito.listeners.StubbingLookupListener; import org.mockito.mock.MockCreationSettings; import org.mockito.stubbing.Stubbing; diff --git a/src/main/java/org/mockito/internal/progress/MockingProgressImpl.java b/src/main/java/org/mockito/internal/progress/MockingProgressImpl.java index 5c4fbbc..2685ddf 100644 --- a/src/main/java/org/mockito/internal/progress/MockingProgressImpl.java +++ b/src/main/java/org/mockito/internal/progress/MockingProgressImpl.java @@ -9,7 +9,6 @@ import org.mockito.internal.configuration.GlobalConfiguration; import org.mockito.internal.debugging.Localized; import org.mockito.internal.debugging.LocationImpl; import org.mockito.internal.exceptions.Reporter; -import org.mockito.internal.listeners.AutoCleanableListener; import org.mockito.invocation.Location; import org.mockito.listeners.MockCreationListener; import org.mockito.listeners.MockitoListener; @@ -20,8 +19,6 @@ import org.mockito.verification.VerificationMode; import org.mockito.verification.VerificationStrategy; import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; import java.util.Set; import static org.mockito.internal.exceptions.Reporter.unfinishedStubbing; @@ -157,28 +154,12 @@ public class MockingProgressImpl implements MockingProgress { } public void addListener(MockitoListener listener) { - addListener(listener, listeners); - } - - static void addListener(MockitoListener listener, Set<MockitoListener> listeners) { - List<MockitoListener> delete = new LinkedList<MockitoListener>(); for (MockitoListener existing : listeners) { if (existing.getClass().equals(listener.getClass())) { - if (existing instanceof AutoCleanableListener && ((AutoCleanableListener) existing).isListenerDirty()) { - //dirty listener means that there was an exception even before the test started - //if we fail here with redundant mockito listener exception there will be multiple failures causing confusion - //so we simply remove the existing listener and move on - delete.add(existing); - } else { - Reporter.redundantMockitoListener(listener.getClass().getSimpleName()); - } + Reporter.redundantMockitoListener(listener.getClass().getSimpleName()); } } - //delete dirty listeners so they don't occupy state/memory and don't receive notifications - for (MockitoListener toDelete : delete) { - listeners.remove(toDelete); - } - listeners.add(listener); + this.listeners.add(listener); } public void removeListener(MockitoListener listener) { diff --git a/src/main/java/org/mockito/internal/reporting/PrintSettings.java b/src/main/java/org/mockito/internal/reporting/PrintSettings.java index 4fc5992..7986c35 100644 --- a/src/main/java/org/mockito/internal/reporting/PrintSettings.java +++ b/src/main/java/org/mockito/internal/reporting/PrintSettings.java @@ -5,6 +5,7 @@ package org.mockito.internal.reporting; import org.mockito.ArgumentMatcher; +import org.mockito.internal.invocation.ArgumentsProcessor; import org.mockito.internal.matchers.text.MatchersPrinter; import org.mockito.internal.util.MockUtil; import org.mockito.invocation.Invocation; @@ -54,7 +55,7 @@ public class PrintSettings { } public String print(Invocation invocation) { - return print(invocation.getArgumentsAsMatchers(), invocation); + return print(ArgumentsProcessor.argumentsToMatchers(invocation.getArguments()), invocation); } public String print(MatchableInvocation invocation) { diff --git a/src/main/java/org/mockito/internal/runners/DefaultInternalRunner.java b/src/main/java/org/mockito/internal/runners/DefaultInternalRunner.java index 93aa32d..2f26ff1 100644 --- a/src/main/java/org/mockito/internal/runners/DefaultInternalRunner.java +++ b/src/main/java/org/mockito/internal/runners/DefaultInternalRunner.java @@ -30,29 +30,34 @@ public class DefaultInternalRunner implements InternalRunner { public Object target; private MockitoTestListener mockitoTestListener; - protected Statement withBefores(FrameworkMethod method, final Object target, Statement statement) { + protected Statement withBefores(FrameworkMethod method, Object target, Statement statement) { this.target = target; - final Statement base = super.withBefores(method, target, statement); - return new Statement() { - @Override - public void evaluate() throws Throwable { - // get new test listener and add it to the framework - mockitoTestListener = listenerSupplier.get(); - Mockito.framework().addListener(mockitoTestListener); - // init annotated mocks before tests - MockitoAnnotations.initMocks(target); - base.evaluate(); - } - }; + // get new test listener and add it to the framework + mockitoTestListener = listenerSupplier.get(); + Mockito.framework().addListener(mockitoTestListener); + // init annotated mocks before tests + MockitoAnnotations.initMocks(target); + return super.withBefores(method, target, statement); } public void run(final RunNotifier notifier) { RunListener listener = new RunListener() { + private boolean started; Throwable failure; @Override + public void testStarted(Description description) throws Exception { + started = true; + } + + @Override public void testFailure(Failure failure) throws Exception { this.failure = failure.getException(); + // If the test fails during the setup, `testFinished` is never invoked + // Therefore, if we have not started, cleanup the testlistener + if (!started && mockitoTestListener != null) { + Mockito.framework().removeListener(mockitoTestListener); + } } @Override diff --git a/src/main/java/org/mockito/internal/runners/RunnerFactory.java b/src/main/java/org/mockito/internal/runners/RunnerFactory.java index efdb6b2..61456dc 100644 --- a/src/main/java/org/mockito/internal/runners/RunnerFactory.java +++ b/src/main/java/org/mockito/internal/runners/RunnerFactory.java @@ -5,12 +5,12 @@ package org.mockito.internal.runners; import org.mockito.exceptions.base.MockitoException; -import org.mockito.internal.configuration.plugins.Plugins; import org.mockito.internal.junit.MismatchReportingTestListener; import org.mockito.internal.junit.MockitoTestListener; import org.mockito.internal.junit.NoOpTestListener; import org.mockito.internal.junit.StrictStubsRunnerTestListener; import org.mockito.internal.runners.util.RunnerProvider; +import org.mockito.internal.util.ConsoleMockitoLogger; import org.mockito.internal.util.Supplier; import java.lang.reflect.InvocationTargetException; @@ -39,7 +39,7 @@ public class RunnerFactory { public InternalRunner createStrict(Class<?> klass) throws InvocationTargetException { return create(klass, new Supplier<MockitoTestListener>() { public MockitoTestListener get() { - return new MismatchReportingTestListener(Plugins.getMockitoLogger()); + return new MismatchReportingTestListener(new ConsoleMockitoLogger()); } }); } diff --git a/src/main/java/org/mockito/internal/session/DefaultMockitoSessionBuilder.java b/src/main/java/org/mockito/internal/session/DefaultMockitoSessionBuilder.java index f47ee15..d9b21e5 100644 --- a/src/main/java/org/mockito/internal/session/DefaultMockitoSessionBuilder.java +++ b/src/main/java/org/mockito/internal/session/DefaultMockitoSessionBuilder.java @@ -5,9 +5,9 @@ package org.mockito.internal.session; import org.mockito.MockitoSession; -import org.mockito.internal.configuration.plugins.Plugins; import org.mockito.internal.framework.DefaultMockitoSession; -import org.mockito.plugins.MockitoLogger; +import org.mockito.internal.util.ConsoleMockitoLogger; +import org.mockito.internal.util.MockitoLogger; import org.mockito.quality.Strictness; import org.mockito.session.MockitoSessionBuilder; import org.mockito.session.MockitoSessionLogger; @@ -74,7 +74,7 @@ public class DefaultMockitoSessionBuilder implements MockitoSessionBuilder { effectiveName = this.name == null ? lastTestClassInstance.getClass().getName() : this.name; } Strictness effectiveStrictness = this.strictness == null ? Strictness.STRICT_STUBS : this.strictness; - MockitoLogger logger = this.logger == null ? Plugins.getMockitoLogger() : new MockitoLoggerAdapter(this.logger); + MockitoLogger logger = this.logger == null ? new ConsoleMockitoLogger() : new MockitoLoggerAdapter(this.logger); return new DefaultMockitoSession(effectiveTestClassInstances, effectiveName, effectiveStrictness, logger); } } diff --git a/src/main/java/org/mockito/internal/session/MockitoLoggerAdapter.java b/src/main/java/org/mockito/internal/session/MockitoLoggerAdapter.java index 2197317..b7329e7 100644 --- a/src/main/java/org/mockito/internal/session/MockitoLoggerAdapter.java +++ b/src/main/java/org/mockito/internal/session/MockitoLoggerAdapter.java @@ -4,7 +4,7 @@ */ package org.mockito.internal.session; -import org.mockito.plugins.MockitoLogger; +import org.mockito.internal.util.MockitoLogger; import org.mockito.session.MockitoSessionLogger; class MockitoLoggerAdapter implements MockitoLogger { diff --git a/src/main/java/org/mockito/internal/session/MockitoSessionLoggerAdapter.java b/src/main/java/org/mockito/internal/session/MockitoSessionLoggerAdapter.java index f4770c5..2e8634b 100644 --- a/src/main/java/org/mockito/internal/session/MockitoSessionLoggerAdapter.java +++ b/src/main/java/org/mockito/internal/session/MockitoSessionLoggerAdapter.java @@ -4,7 +4,7 @@ */ package org.mockito.internal.session; -import org.mockito.plugins.MockitoLogger; +import org.mockito.internal.util.MockitoLogger; import org.mockito.session.MockitoSessionLogger; public class MockitoSessionLoggerAdapter implements MockitoSessionLogger { diff --git a/src/main/java/org/mockito/internal/stubbing/BaseStubbing.java b/src/main/java/org/mockito/internal/stubbing/BaseStubbing.java index 4c86cbd..6dd99cd 100644 --- a/src/main/java/org/mockito/internal/stubbing/BaseStubbing.java +++ b/src/main/java/org/mockito/internal/stubbing/BaseStubbing.java @@ -4,31 +4,17 @@ */ package org.mockito.internal.stubbing; +import static org.mockito.internal.exceptions.Reporter.notAnException; +import static org.mockito.internal.progress.ThreadSafeMockingProgress.mockingProgress; +import static org.objenesis.ObjenesisHelper.newInstance; + import org.mockito.internal.stubbing.answers.CallsRealMethods; import org.mockito.internal.stubbing.answers.Returns; import org.mockito.internal.stubbing.answers.ThrowsException; -import org.mockito.stubbing.Answer; import org.mockito.stubbing.OngoingStubbing; -import static org.mockito.internal.exceptions.Reporter.notAnException; -import static org.mockito.internal.progress.ThreadSafeMockingProgress.mockingProgress; -import static org.objenesis.ObjenesisHelper.newInstance; - public abstract class BaseStubbing<T> implements OngoingStubbing<T> { - - // Keep strong ref to mock preventing premature garbage collection when using 'One-liner stubs'. See #1541. - private final Object strongMockRef; - - BaseStubbing(Object mock) { - this.strongMockRef = mock; - } - - @Override - public OngoingStubbing<T> then(Answer<?> answer) { - return thenAnswer(answer); - } - @Override public OngoingStubbing<T> thenReturn(T value) { return thenAnswer(new Returns(value)); @@ -93,12 +79,6 @@ public abstract class BaseStubbing<T> implements OngoingStubbing<T> { public OngoingStubbing<T> thenCallRealMethod() { return thenAnswer(new CallsRealMethods()); } - - @Override - @SuppressWarnings("unchecked") - public <M> M getMock() { - return (M) this.strongMockRef; - } } diff --git a/src/main/java/org/mockito/internal/stubbing/ConsecutiveStubbing.java b/src/main/java/org/mockito/internal/stubbing/ConsecutiveStubbing.java index 32ef8ee..a5cdc04 100644 --- a/src/main/java/org/mockito/internal/stubbing/ConsecutiveStubbing.java +++ b/src/main/java/org/mockito/internal/stubbing/ConsecutiveStubbing.java @@ -8,17 +8,23 @@ import org.mockito.stubbing.Answer; import org.mockito.stubbing.OngoingStubbing; public class ConsecutiveStubbing<T> extends BaseStubbing<T> { + private final InvocationContainerImpl invocationContainerImpl; - private final InvocationContainerImpl invocationContainer; - - ConsecutiveStubbing(InvocationContainerImpl invocationContainer) { - super(invocationContainer.invokedMock()); - this.invocationContainer = invocationContainer; + public ConsecutiveStubbing(InvocationContainerImpl invocationContainerImpl) { + this.invocationContainerImpl = invocationContainerImpl; } public OngoingStubbing<T> thenAnswer(Answer<?> answer) { - invocationContainer.addConsecutiveAnswer(answer); + invocationContainerImpl.addConsecutiveAnswer(answer); return this; } + public OngoingStubbing<T> then(Answer<?> answer) { + return thenAnswer(answer); + } + + @SuppressWarnings("unchecked") + public <M> M getMock() { + return (M) invocationContainerImpl.invokedMock(); + } } diff --git a/src/main/java/org/mockito/internal/stubbing/OngoingStubbingImpl.java b/src/main/java/org/mockito/internal/stubbing/OngoingStubbingImpl.java index 4191604..cd27c39 100644 --- a/src/main/java/org/mockito/internal/stubbing/OngoingStubbingImpl.java +++ b/src/main/java/org/mockito/internal/stubbing/OngoingStubbingImpl.java @@ -19,7 +19,6 @@ public class OngoingStubbingImpl<T> extends BaseStubbing<T> { private Strictness strictness; public OngoingStubbingImpl(InvocationContainerImpl invocationContainer) { - super(invocationContainer.invokedMock()); this.invocationContainer = invocationContainer; } @@ -33,11 +32,22 @@ public class OngoingStubbingImpl<T> extends BaseStubbing<T> { return new ConsecutiveStubbing<T>(invocationContainer); } + @Override + public OngoingStubbing<T> then(Answer<?> answer) { + return thenAnswer(answer); + } + public List<Invocation> getRegisteredInvocations() { //TODO interface for tests return invocationContainer.getInvocations(); } + @Override + @SuppressWarnings("unchecked") + public <M> M getMock() { + return (M) invocationContainer.invokedMock(); + } + public void setStrictness(Strictness strictness) { this.strictness = strictness; } diff --git a/src/main/java/org/mockito/internal/stubbing/StubberImpl.java b/src/main/java/org/mockito/internal/stubbing/StubberImpl.java index 42795a7..2172809 100644 --- a/src/main/java/org/mockito/internal/stubbing/StubberImpl.java +++ b/src/main/java/org/mockito/internal/stubbing/StubberImpl.java @@ -87,16 +87,12 @@ public class StubberImpl implements Stubber { mockingProgress().reset(); throw notAnException(); } - Throwable e = null; + Throwable e; try { e = newInstance(toBeThrown); - } finally { - if (e == null) { - //this means that an exception or error was thrown when trying to create new instance - //we don't want 'catch' statement here because we want the exception to be thrown to the user - //however, we do want to clean up state (e.g. "stubbing started"). - mockingProgress().reset(); - } + } catch (RuntimeException instantiationError) { + mockingProgress().reset(); + throw instantiationError; } return doThrow(e); } diff --git a/src/main/java/org/mockito/internal/stubbing/answers/AnswerFunctionalInterfaces.java b/src/main/java/org/mockito/internal/stubbing/answers/AnswerFunctionalInterfaces.java index eaa6493..e1a92a4 100644 --- a/src/main/java/org/mockito/internal/stubbing/answers/AnswerFunctionalInterfaces.java +++ b/src/main/java/org/mockito/internal/stubbing/answers/AnswerFunctionalInterfaces.java @@ -11,13 +11,11 @@ import org.mockito.stubbing.Answer2; import org.mockito.stubbing.Answer3; import org.mockito.stubbing.Answer4; import org.mockito.stubbing.Answer5; -import org.mockito.stubbing.Answer6; import org.mockito.stubbing.VoidAnswer1; import org.mockito.stubbing.VoidAnswer2; import org.mockito.stubbing.VoidAnswer3; import org.mockito.stubbing.VoidAnswer4; import org.mockito.stubbing.VoidAnswer5; -import org.mockito.stubbing.VoidAnswer6; /** * Functional interfaces to make it easy to implement answers in Java 8 @@ -238,60 +236,4 @@ public class AnswerFunctionalInterfaces { } }; } - - /** - * Construct an answer from a six parameter answer interface - * - * @param answer answer interface - * @param <T> return type - * @param <A> input parameter 1 type - * @param <B> input parameter 2 type - * @param <C> input parameter 3 type - * @param <D> input parameter 4 type - * @param <E> input parameter 5 type - * @param <F> input parameter 6 type - * @return a new answer object - */ - public static <T, A, B, C, D, E, F> Answer<T> toAnswer(final Answer6<T, A, B, C, D, E, F> answer) { - return new Answer<T>() { - @SuppressWarnings("unchecked") - public T answer(InvocationOnMock invocation) throws Throwable { - return answer.answer( - (A)invocation.getArgument(0), - (B)invocation.getArgument(1), - (C)invocation.getArgument(2), - (D)invocation.getArgument(3), - (E)invocation.getArgument(4), - (F)invocation.getArgument(5)); - } - }; - } - - /** - * Construct an answer from a five parameter answer interface - - * @param answer answer interface - * @param <A> input parameter 1 type - * @param <B> input parameter 2 type - * @param <C> input parameter 3 type - * @param <D> input parameter 4 type - * @param <E> input parameter 5 type - * @param <F> input parameter 6 type - * @return a new answer object - */ - public static <A, B, C, D, E, F> Answer<Void> toAnswer(final VoidAnswer6<A, B, C, D, E, F> answer) { - return new Answer<Void>() { - @SuppressWarnings("unchecked") - public Void answer(InvocationOnMock invocation) throws Throwable { - answer.answer( - (A)invocation.getArgument(0), - (B)invocation.getArgument(1), - (C)invocation.getArgument(2), - (D)invocation.getArgument(3), - (E)invocation.getArgument(4), - (F)invocation.getArgument(5)); - return null; - } - }; - } } diff --git a/src/main/java/org/mockito/internal/stubbing/defaultanswers/ForwardsInvocations.java b/src/main/java/org/mockito/internal/stubbing/defaultanswers/ForwardsInvocations.java index 7ef283c..9165142 100644 --- a/src/main/java/org/mockito/internal/stubbing/defaultanswers/ForwardsInvocations.java +++ b/src/main/java/org/mockito/internal/stubbing/defaultanswers/ForwardsInvocations.java @@ -40,11 +40,6 @@ public class ForwardsInvocations implements Answer<Object>, Serializable { } Object[] rawArguments = ((Invocation) invocation).getRawArguments(); - try { - delegateMethod.setAccessible(true); - } catch (SecurityException ignore) { - // try to invoke anyway - } return delegateMethod.invoke(delegatedObject, rawArguments); } catch (NoSuchMethodException e) { throw delegatedMethodDoesNotExistOnDelegate(mockMethod, invocation.getMock(), delegatedObject); diff --git a/src/main/java/org/mockito/internal/stubbing/defaultanswers/RetrieveGenericsForDefaultAnswers.java b/src/main/java/org/mockito/internal/stubbing/defaultanswers/RetrieveGenericsForDefaultAnswers.java deleted file mode 100644 index 979c8f7..0000000 --- a/src/main/java/org/mockito/internal/stubbing/defaultanswers/RetrieveGenericsForDefaultAnswers.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2007 Mockito contributors - * This program is made available under the terms of the MIT License. - */ -package org.mockito.internal.stubbing.defaultanswers; - -import java.lang.reflect.GenericArrayType; -import java.lang.reflect.Type; -import java.lang.reflect.TypeVariable; -import org.mockito.internal.MockitoCore; -import org.mockito.internal.util.MockUtil; -import org.mockito.internal.util.reflection.GenericMetadataSupport; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.mock.MockCreationSettings; - -class RetrieveGenericsForDefaultAnswers { - - private static final MockitoCore MOCKITO_CORE = new MockitoCore(); - - static Object returnTypeForMockWithCorrectGenerics( - InvocationOnMock invocation, AnswerCallback answerCallback) { - Class<?> type = invocation.getMethod().getReturnType(); - - final Type returnType = invocation.getMethod().getGenericReturnType(); - - Object defaultReturnValue = null; - - if (returnType instanceof TypeVariable) { - type = findTypeFromGeneric(invocation, (TypeVariable) returnType); - if (type != null) { - defaultReturnValue = delegateChains(type); - } - } - - if (defaultReturnValue != null) { - return defaultReturnValue; - } - - if (type != null) { - if (!MOCKITO_CORE.isTypeMockable(type)) { - return null; - } - - return answerCallback.apply(type); - } - - return answerCallback.apply(null); - } - - /** - * Try to resolve the result value using {@link ReturnsEmptyValues} and {@link ReturnsMoreEmptyValues}. - * - * This will try to use all parent class (superclass & interfaces) to retrieve the value.. - * - * @param type the return type of the method - * @return a non-null instance if the type has been resolve. Null otherwise. - */ - private static Object delegateChains(final Class<?> type) { - final ReturnsEmptyValues returnsEmptyValues = new ReturnsEmptyValues(); - Object result = returnsEmptyValues.returnValueFor(type); - - if (result == null) { - Class<?> emptyValueForClass = type; - while (emptyValueForClass != null && result == null) { - final Class<?>[] classes = emptyValueForClass.getInterfaces(); - for (Class<?> clazz : classes) { - result = returnsEmptyValues.returnValueFor(clazz); - if (result != null) { - break; - } - } - emptyValueForClass = emptyValueForClass.getSuperclass(); - } - } - - if (result == null) { - result = new ReturnsMoreEmptyValues().returnValueFor(type); - } - - return result; - } - - /** - * Retrieve the expected type when it came from a primitive. If the type cannot be retrieve, return null. - * - * @param invocation the current invocation - * @param returnType the expected return type - * @return the type or null if not found - */ - private static Class<?> findTypeFromGeneric(final InvocationOnMock invocation, final TypeVariable returnType) { - // Class level - final MockCreationSettings mockSettings = MockUtil.getMockHandler(invocation.getMock()).getMockSettings(); - final GenericMetadataSupport returnTypeSupport = GenericMetadataSupport - .inferFrom(mockSettings.getTypeToMock()) - .resolveGenericReturnType(invocation.getMethod()); - final Class<?> rawType = returnTypeSupport.rawType(); - - // Method level - if (rawType == Object.class) { - return findTypeFromGenericInArguments(invocation, returnType); - } - return rawType; - } - - /** - * Find a return type using generic arguments provided by the calling method. - * - * @param invocation the current invocation - * @param returnType the expected return type - * @return the return type or null if the return type cannot be found - */ - private static Class<?> findTypeFromGenericInArguments(final InvocationOnMock invocation, final TypeVariable returnType) { - final Type[] parameterTypes = invocation.getMethod().getGenericParameterTypes(); - for (int i = 0; i < parameterTypes.length; i++) { - Type argType = parameterTypes[i]; - if (returnType.equals(argType)) { - Object argument = invocation.getArgument(i); - - if (argument == null) { - return null; - } - - return argument.getClass(); - } - if (argType instanceof GenericArrayType) { - argType = ((GenericArrayType) argType).getGenericComponentType(); - if (returnType.equals(argType)) { - return invocation.getArgument(i).getClass(); - } - } - } - return null; - } - - interface AnswerCallback { - Object apply(Class<?> type); - } -} diff --git a/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsDeepStubs.java b/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsDeepStubs.java index 356b2e6..3909ff0 100644 --- a/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsDeepStubs.java +++ b/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsDeepStubs.java @@ -25,7 +25,7 @@ import static org.mockito.Mockito.withSettings; /** * Returning deep stub implementation. * - * <p>Will return previously created mock if the invocation matches. + * Will return previously created mock if the invocation matches. * * <p>Supports nested generic information, with this answer you can write code like this : * @@ -37,8 +37,6 @@ import static org.mockito.Mockito.withSettings; * </code></pre> * </p> * - * <p>However this answer does not support generics information when the mock has been deserialized. - * * @see org.mockito.Mockito#RETURNS_DEEP_STUBS * @see org.mockito.Answers#RETURNS_DEEP_STUBS */ @@ -48,22 +46,13 @@ public class ReturnsDeepStubs implements Answer<Object>, Serializable { public Object answer(InvocationOnMock invocation) throws Throwable { GenericMetadataSupport returnTypeGenericMetadata = - actualParameterizedType(invocation.getMock()).resolveGenericReturnType(invocation.getMethod()); + actualParameterizedType(invocation.getMock()).resolveGenericReturnType(invocation.getMethod()); Class<?> rawType = returnTypeGenericMetadata.rawType(); if (!mockitoCore().isTypeMockable(rawType)) { return delegate().returnValueFor(rawType); } - // When dealing with erased generics, we only receive the Object type as rawType. At this - // point, there is nothing to salvage for Mockito. Instead of trying to be smart and generate - // a mock that would potentially match the return signature, instead return `null`. This - // is valid per the CheckCast JVM instruction and is better than causing a ClassCastException - // on runtime. - if (rawType.equals(Object.class) && !returnTypeGenericMetadata.hasRawExtraInterfaces()) { - return null; - } - return deepStub(invocation, returnTypeGenericMetadata); } @@ -80,9 +69,9 @@ public class ReturnsDeepStubs implements Answer<Object>, Serializable { // record deep stub answer StubbedInvocationMatcher stubbing = recordDeepStubAnswer( - newDeepStubMock(returnTypeGenericMetadata, invocation.getMock()), - container - ); + newDeepStubMock(returnTypeGenericMetadata, invocation.getMock()), + container + ); // deep stubbing creates a stubbing and immediately uses it // so the stubbing is actually used by the same invocation @@ -99,24 +88,24 @@ public class ReturnsDeepStubs implements Answer<Object>, Serializable { * {@link ReturnsDeepStubs} answer in which we will store the returned type generic metadata. * * @param returnTypeGenericMetadata The metadata to use to create the new mock. - * @param parentMock The parent of the current deep stub mock. + * @param parentMock The parent of the current deep stub mock. * @return The mock */ private Object newDeepStubMock(GenericMetadataSupport returnTypeGenericMetadata, Object parentMock) { MockCreationSettings parentMockSettings = MockUtil.getMockSettings(parentMock); return mockitoCore().mock( - returnTypeGenericMetadata.rawType(), - withSettingsUsing(returnTypeGenericMetadata, parentMockSettings) - ); + returnTypeGenericMetadata.rawType(), + withSettingsUsing(returnTypeGenericMetadata, parentMockSettings) + ); } private MockSettings withSettingsUsing(GenericMetadataSupport returnTypeGenericMetadata, MockCreationSettings parentMockSettings) { MockSettings mockSettings = returnTypeGenericMetadata.hasRawExtraInterfaces() ? - withSettings().extraInterfaces(returnTypeGenericMetadata.rawExtraInterfaces()) - : withSettings(); + withSettings().extraInterfaces(returnTypeGenericMetadata.rawExtraInterfaces()) + : withSettings(); return propagateSerializationSettings(mockSettings, parentMockSettings) - .defaultAnswer(returnsDeepStubsAnswerUsing(returnTypeGenericMetadata)); + .defaultAnswer(returnsDeepStubsAnswerUsing(returnTypeGenericMetadata)); } private MockSettings propagateSerializationSettings(MockSettings mockSettings, MockCreationSettings parentMockSettings) { @@ -150,15 +139,6 @@ public class ReturnsDeepStubs implements Answer<Object>, Serializable { protected GenericMetadataSupport actualParameterizedType(Object mock) { return returnTypeGenericMetadata; } - - /** - * Generics support and serialization with deep stubs don't work together. - * <p> - * The issue is that GenericMetadataSupport is not serializable because - * the type elements inferred via reflection are not serializable. Supporting - * serialization would require to replace all types coming from the Java reflection - * with our own and still managing type equality with the JDK ones. - */ private Object writeReplace() throws IOException { return Mockito.RETURNS_DEEP_STUBS; } @@ -172,7 +152,6 @@ public class ReturnsDeepStubs implements Answer<Object>, Serializable { DeeplyStubbedAnswer(Object mock) { this.mock = mock; } - public Object answer(InvocationOnMock invocation) throws Throwable { return mock; } diff --git a/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsMocks.java b/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsMocks.java index 5d4befe..302e4df 100755 --- a/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsMocks.java +++ b/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsMocks.java @@ -4,36 +4,33 @@ */ package org.mockito.internal.stubbing.defaultanswers; -import java.io.Serializable; -import org.mockito.Mockito; +import org.mockito.internal.MockitoCore; import org.mockito.internal.creation.MockSettingsImpl; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; +import java.io.Serializable; + public class ReturnsMocks implements Answer<Object>, Serializable { private static final long serialVersionUID = -6755257986994634579L; + private final MockitoCore mockitoCore = new MockitoCore(); private final Answer<Object> delegate = new ReturnsMoreEmptyValues(); - @Override - public Object answer(final InvocationOnMock invocation) throws Throwable { - Object defaultReturnValue = delegate.answer(invocation); + public Object answer(InvocationOnMock invocation) throws Throwable { + Object ret = delegate.answer(invocation); + if (ret != null) { + return ret; + } + + return returnValueFor(invocation.getMethod().getReturnType()); + } - if (defaultReturnValue != null) { - return defaultReturnValue; + Object returnValueFor(Class<?> clazz) { + if (!mockitoCore.isTypeMockable(clazz)) { + return null; } - return RetrieveGenericsForDefaultAnswers.returnTypeForMockWithCorrectGenerics(invocation, - new RetrieveGenericsForDefaultAnswers.AnswerCallback() { - @Override - public Object apply(Class<?> type) { - if (type == null) { - type = invocation.getMethod().getReturnType(); - } - - return Mockito - .mock(type, new MockSettingsImpl<Object>().defaultAnswer(ReturnsMocks.this)); - } - }); + return mockitoCore.mock(clazz, new MockSettingsImpl().defaultAnswer(this)); } } diff --git a/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsSmartNulls.java b/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsSmartNulls.java index 6cf50c7..7487e89 100644 --- a/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsSmartNulls.java +++ b/src/main/java/org/mockito/internal/stubbing/defaultanswers/ReturnsSmartNulls.java @@ -8,6 +8,8 @@ import static org.mockito.internal.exceptions.Reporter.smartNullPointerException import static org.mockito.internal.util.ObjectMethodsGuru.isToStringMethod; import java.io.Serializable; +import java.lang.reflect.Modifier; + import org.mockito.Mockito; import org.mockito.internal.debugging.LocationImpl; import org.mockito.invocation.InvocationOnMock; @@ -38,34 +40,24 @@ public class ReturnsSmartNulls implements Answer<Object>, Serializable { private final Answer<Object> delegate = new ReturnsMoreEmptyValues(); - @Override public Object answer(final InvocationOnMock invocation) throws Throwable { Object defaultReturnValue = delegate.answer(invocation); - if (defaultReturnValue != null) { return defaultReturnValue; } - - return RetrieveGenericsForDefaultAnswers.returnTypeForMockWithCorrectGenerics(invocation, - new RetrieveGenericsForDefaultAnswers.AnswerCallback() { - @Override - public Object apply(Class<?> type) { - if (type == null) { - return null; - } - - return Mockito.mock(type, new ThrowsSmartNullPointer(invocation, new LocationImpl())); - } - }); + Class<?> type = invocation.getMethod().getReturnType(); + if (!type.isPrimitive() && !Modifier.isFinal(type.getModifiers())) { + final Location location = new LocationImpl(); + return Mockito.mock(type, new ThrowsSmartNullPointer(invocation, location)); + } + return null; } private static class ThrowsSmartNullPointer implements Answer { - private final InvocationOnMock unstubbedInvocation; - private final Location location; - ThrowsSmartNullPointer(InvocationOnMock unstubbedInvocation, Location location) { + public ThrowsSmartNullPointer(InvocationOnMock unstubbedInvocation, Location location) { this.unstubbedInvocation = unstubbedInvocation; this.location = location; } @@ -73,7 +65,7 @@ public class ReturnsSmartNulls implements Answer<Object>, Serializable { public Object answer(InvocationOnMock currentInvocation) throws Throwable { if (isToStringMethod(currentInvocation.getMethod())) { return "SmartNull returned by this unstubbed method call on a mock:\n" + - unstubbedInvocation.toString(); + unstubbedInvocation.toString(); } throw smartNullPointerException(unstubbedInvocation.toString(), location); diff --git a/src/main/java/org/mockito/internal/util/ConsoleMockitoLogger.java b/src/main/java/org/mockito/internal/util/ConsoleMockitoLogger.java index 3eb8939..d8df8eb 100644 --- a/src/main/java/org/mockito/internal/util/ConsoleMockitoLogger.java +++ b/src/main/java/org/mockito/internal/util/ConsoleMockitoLogger.java @@ -4,8 +4,6 @@ */ package org.mockito.internal.util; -import org.mockito.plugins.MockitoLogger; - public class ConsoleMockitoLogger implements MockitoLogger { /* (non-Javadoc) diff --git a/src/main/java/org/mockito/internal/util/reflection/GenericMetadataSupport.java b/src/main/java/org/mockito/internal/util/reflection/GenericMetadataSupport.java index 80cbf65..8efd384 100644 --- a/src/main/java/org/mockito/internal/util/reflection/GenericMetadataSupport.java +++ b/src/main/java/org/mockito/internal/util/reflection/GenericMetadataSupport.java @@ -8,23 +8,8 @@ package org.mockito.internal.util.reflection; import org.mockito.exceptions.base.MockitoException; import org.mockito.internal.util.Checks; -import java.lang.reflect.GenericArrayType; -import java.lang.reflect.Method; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.lang.reflect.TypeVariable; -import java.lang.reflect.WildcardType; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Queue; -import java.util.Set; +import java.lang.reflect.*; +import java.util.*; /** @@ -32,20 +17,20 @@ import java.util.Set; * and accessible members. * * <p> - * The main idea of this code is to create a Map that will help to resolve return types. - * In order to actually work with nested generics, this map will have to be passed along new instances - * as a type context. + * The main idea of this code is to create a Map that will help to resolve return types. + * In order to actually work with nested generics, this map will have to be passed along new instances + * as a type context. * </p> * * <p> - * Hence : - * <ul> - * <li>A new instance representing the metadata is created using the {@link #inferFrom(Type)} method from a real - * <code>Class</code> or from a <code>ParameterizedType</code>, other types are not yet supported.</li> + * Hence : + * <ul> + * <li>A new instance representing the metadata is created using the {@link #inferFrom(Type)} method from a real + * <code>Class</code> or from a <code>ParameterizedType</code>, other types are not yet supported.</li> * - * <li>Then from this metadata, we can extract meta-data for a generic return type of a method, using - * {@link #resolveGenericReturnType(Method)}.</li> - * </ul> + * <li>Then from this metadata, we can extract meta-data for a generic return type of a method, using + * {@link #resolveGenericReturnType(Method)}.</li> + * </ul> * </p> * * <p> @@ -112,9 +97,8 @@ public abstract class GenericMetadataSupport { } if (type instanceof TypeVariable) { /* - * If type is a TypeVariable, then it is needed to gather data elsewhere. - * Usually TypeVariables are declared on the class definition, such as such - * as List<E>. + * If type is a TypeVariable, then it is needed to gather data elsewhere. Usually TypeVariables are declared + * on the class definition, such as such as List<E>. */ return extractRawTypeOf(contextualActualTypeParameters.get(type)); } @@ -132,23 +116,6 @@ public abstract class GenericMetadataSupport { TypeVariable<?> typeParameter = typeParameters[i]; Type actualTypeArgument = actualTypeArguments[i]; - if (actualTypeArgument instanceof TypeVariable) { - /* - * If actualTypeArgument is a TypeVariable, and it is not present in - * the context map then it is needed to try harder to gather more data - * from the type argument itself. In some case the type argument do - * define upper bounds, this allow to look for them if not in the - * context map. - */ - registerTypeVariableIfNotPresent((TypeVariable<?>) actualTypeArgument); - - // Prevent registration of a cycle of TypeVariables. This can happen when we are processing - // type parameters in a Method, while we already processed the type parameters of a class. - if (contextualActualTypeParameters.containsKey(typeParameter)) { - continue; - } - } - if (actualTypeArgument instanceof WildcardType) { contextualActualTypeParameters.put(typeParameter, boundsOf((WildcardType) actualTypeArgument)); } else if (typeParameter != actualTypeArgument) { @@ -174,7 +141,7 @@ public abstract class GenericMetadataSupport { /** * @param typeParameter The TypeVariable parameter * @return A {@link BoundedType} for easy bound information, if first bound is a TypeVariable - * then retrieve BoundedType of this TypeVariable + * then retrieve BoundedType of this TypeVariable */ private BoundedType boundsOf(TypeVariable<?> typeParameter) { if (typeParameter.getBounds()[0] instanceof TypeVariable) { @@ -186,17 +153,13 @@ public abstract class GenericMetadataSupport { /** * @param wildCard The WildCard type * @return A {@link BoundedType} for easy bound information, if first bound is a TypeVariable - * then retrieve BoundedType of this TypeVariable + * then retrieve BoundedType of this TypeVariable */ private BoundedType boundsOf(WildcardType wildCard) { /* * According to JLS(http://docs.oracle.com/javase/specs/jls/se5.0/html/typesValues.html#4.5.1): - * - Lower and upper can't coexist: (for instance, this is not allowed: - * <? extends List<String> & super MyInterface>) - * - Multiple concrete type bounds are not supported (for instance, this is not allowed: - * <? extends ArrayList<String> & MyInterface>) - * But the following form is possible where there is a single concrete tyep bound followed by interface type bounds - * <T extends List<String> & Comparable> + * - Lower and upper can't coexist: (for instance, this is not allowed: <? extends List<String> & super MyInterface>) + * - Multiple bounds are not supported (for instance, this is not allowed: <? extends List<String> & MyInterface>) */ WildCardBoundedType wildCardBoundedType = new WildCardBoundedType(wildCard); @@ -272,7 +235,7 @@ public abstract class GenericMetadataSupport { // logger.log("Method '" + method.toGenericString() + "' has return type : " + genericReturnType.getClass().getInterfaces()[0].getSimpleName() + " : " + genericReturnType); int arity = 0; - while (genericReturnType instanceof GenericArrayType) { + while(genericReturnType instanceof GenericArrayType) { arity++; genericReturnType = ((GenericArrayType) genericReturnType).getGenericComponentType(); } @@ -304,8 +267,8 @@ public abstract class GenericMetadataSupport { * Create an new instance of {@link GenericMetadataSupport} inferred from a {@link Type}. * * <p> - * At the moment <code>type</code> can only be a {@link Class} or a {@link ParameterizedType}, otherwise - * it'll throw a {@link MockitoException}. + * At the moment <code>type</code> can only be a {@link Class} or a {@link ParameterizedType}, otherwise + * it'll throw a {@link MockitoException}. * </p> * * @param type The class from which the {@link GenericMetadataSupport} should be built. @@ -331,7 +294,7 @@ public abstract class GenericMetadataSupport { /** * Generic metadata implementation for {@link Class}. - * <p> + * * Offer support to retrieve generic metadata on a {@link Class} by reading type parameters and type variables on * the class and its ancestors and interfaces. */ @@ -353,10 +316,10 @@ public abstract class GenericMetadataSupport { /** * Generic metadata implementation for "standalone" {@link ParameterizedType}. - * <p> + * * Offer support to retrieve generic metadata on a {@link ParameterizedType} by reading type variables of * the related raw type and declared type variable of this parameterized type. - * <p> + * * This class is not designed to work on ParameterizedType returned by {@link Method#getGenericReturnType()}, as * the ParameterizedType instance return in these cases could have Type Variables that refer to type declaration(s). * That's what meant the "standalone" word at the beginning of the Javadoc. @@ -418,7 +381,6 @@ public abstract class GenericMetadataSupport { private final TypeVariable<?> typeVariable; private final TypeVariable<?>[] typeParameters; private Class<?> rawType; - private List<Type> extraInterfaces; public TypeVariableReturnType(GenericMetadataSupport source, TypeVariable<?>[] typeParameters, TypeVariable<?> typeVariable) { this.typeParameters = typeParameters; @@ -437,7 +399,7 @@ public abstract class GenericMetadataSupport { for (Type type : typeVariable.getBounds()) { registerTypeVariablesOn(type); } - registerTypeParametersOn(new TypeVariable[]{typeVariable}); + registerTypeParametersOn(new TypeVariable[] { typeVariable }); registerTypeVariablesOn(getActualTypeArgumentFor(typeVariable)); } @@ -451,18 +413,15 @@ public abstract class GenericMetadataSupport { @Override public List<Type> extraInterfaces() { - if (extraInterfaces != null) { - return extraInterfaces; - } Type type = extractActualBoundedTypeOf(typeVariable); if (type instanceof BoundedType) { - return extraInterfaces = Arrays.asList(((BoundedType) type).interfaceBounds()); + return Arrays.asList(((BoundedType) type).interfaceBounds()); } if (type instanceof ParameterizedType) { - return extraInterfaces = Collections.singletonList(type); + return Collections.singletonList(type); } if (type instanceof Class) { - return extraInterfaces = Collections.emptyList(); + return Collections.emptyList(); } throw new MockitoException("Cannot extract extra-interfaces from '" + typeVariable + "' : '" + type + "'"); } @@ -477,7 +436,7 @@ public abstract class GenericMetadataSupport { for (Type extraInterface : extraInterfaces) { Class<?> rawInterface = extractRawTypeOf(extraInterface); // avoid interface collision with actual raw type (with typevariables, resolution ca be quite aggressive) - if (!rawType().equals(rawInterface)) { + if(!rawType().equals(rawInterface)) { rawExtraInterfaces.add(rawInterface); } } @@ -549,6 +508,7 @@ public abstract class GenericMetadataSupport { } + /** * Type representing bounds of a type * @@ -571,7 +531,7 @@ public abstract class GenericMetadataSupport { * * <p>If upper bounds are declared with SomeClass and additional interfaces, then firstBound will be SomeClass and * interfacesBound will be an array of the additional interfaces. - * <p> + * * i.e. <code>SomeClass</code>. * <pre class="code"><code class="java"> * interface UpperBoundedTypeWithClass<E extends Comparable<E> & Cloneable> { diff --git a/src/main/java/org/mockito/internal/verification/VerificationWrapperInOrderWrapper.java b/src/main/java/org/mockito/internal/verification/VerificationWrapperInOrderWrapper.java index 840efb7..eded985 100644 --- a/src/main/java/org/mockito/internal/verification/VerificationWrapperInOrderWrapper.java +++ b/src/main/java/org/mockito/internal/verification/VerificationWrapperInOrderWrapper.java @@ -47,7 +47,6 @@ public class VerificationWrapperInOrderWrapper implements VerificationMode { } } - //TODO ugly exception message!!! throw new MockitoException(verificationMode.getClass().getSimpleName() + " is not implemented to work with InOrder wrapped inside a " + verificationWrapper.getClass().getSimpleName()); diff --git a/src/main/java/org/mockito/invocation/Invocation.java b/src/main/java/org/mockito/invocation/Invocation.java index fa2e324..131db84 100644 --- a/src/main/java/org/mockito/invocation/Invocation.java +++ b/src/main/java/org/mockito/invocation/Invocation.java @@ -4,11 +4,8 @@ */ package org.mockito.invocation; -import org.mockito.ArgumentMatcher; import org.mockito.NotExtensible; -import java.util.List; - /** * A method call on a mock object. Contains all information and state needed for the Mockito framework to operate. * This API might be useful for developers who extend Mockito. @@ -51,16 +48,6 @@ public interface Invocation extends InvocationOnMock, DescribedInvocation { Object[] getRawArguments(); /** - * Wraps each argument using {@link org.mockito.ArgumentMatchers#eq(Object)} or - * {@link org.mockito.AdditionalMatchers#aryEq(Object[])} - * Used internally for the purposes of human-readable invocation printing. - * - * @return a list of {@link ArgumentMatcher} wrapping each of this invocation arguments - * @since 2.25.6 - */ - List<ArgumentMatcher> getArgumentsAsMatchers(); - - /** * Returns unprocessed arguments whereas {@link #getArguments()} returns * arguments already processed (e.g. varargs expended, etc.). * diff --git a/src/main/java/org/mockito/invocation/InvocationOnMock.java b/src/main/java/org/mockito/invocation/InvocationOnMock.java index 8fabfa0..345ddb9 100644 --- a/src/main/java/org/mockito/invocation/InvocationOnMock.java +++ b/src/main/java/org/mockito/invocation/InvocationOnMock.java @@ -7,7 +7,6 @@ package org.mockito.invocation; import java.io.Serializable; import java.lang.reflect.Method; -import org.mockito.NotExtensible; /** * An invocation on a mock. @@ -15,7 +14,6 @@ import org.mockito.NotExtensible; * <p> * A placeholder for mock, the method that was called and the arguments that were passed. */ -@NotExtensible public interface InvocationOnMock extends Serializable { /** @@ -46,10 +44,6 @@ public interface InvocationOnMock extends Serializable { * * Can lookup in expanded arguments form {@link #getArguments()}. * - * This method is preferred over {@link #getArgument(int, Class)} for readability. Please read - * the documentation of {@link #getArgument(int, Class)} for an overview of situations when - * that method is preferred over this one. - * * @param index argument index * @return casted argument at the given index * @since 2.1.0 @@ -57,25 +51,6 @@ public interface InvocationOnMock extends Serializable { <T> T getArgument(int index); /** - * Returns casted argument at the given index. This method is analogous to - * {@link #getArgument(int)}, but is necessary to circumvent issues when dealing with generics. - * - * In general, {@link #getArgument(int)} is the appropriate function to use. This particular - * function is only necessary if you are doing one of the following things: - * - * 1. You want to directly invoke a method on the result of {@link #getArgument(int)}. - * 2. You want to directly pas the result of the invocation into a function that accepts a generic parameter. - * - * If you prefer to use {@link #getArgument(int)} instead, you can circumvent the compilation - * issues by storing the intermediate result into a local variable with the correct type. - * - * @param index argument index - * @param clazz clazz to cast the argument to - * @return casted argument at the given index - */ - <T> T getArgument(int index, Class<T> clazz); - - /** * calls real method * <p> * <b>Warning:</b> depending on the real implementation it might throw exceptions diff --git a/src/main/java/org/mockito/invocation/Location.java b/src/main/java/org/mockito/invocation/Location.java index 43b4832..e362704 100644 --- a/src/main/java/org/mockito/invocation/Location.java +++ b/src/main/java/org/mockito/invocation/Location.java @@ -4,26 +4,14 @@ */ package org.mockito.invocation; -import org.mockito.NotExtensible; - /** * Describes the location of something in the source code. */ -@NotExtensible public interface Location { /** - * Human readable location in the source code, see {@link Invocation#getLocation()} - * - * @return location + * @return the location */ String toString(); - /** - * Source file of this location - * - * @return source file - * @since 2.24.6 - */ - String getSourceFile(); } diff --git a/src/main/java/org/mockito/junit/MockitoJUnit.java b/src/main/java/org/mockito/junit/MockitoJUnit.java index c0fb55b..da9428b 100644 --- a/src/main/java/org/mockito/junit/MockitoJUnit.java +++ b/src/main/java/org/mockito/junit/MockitoJUnit.java @@ -5,9 +5,9 @@ package org.mockito.junit; import org.mockito.Incubating; -import org.mockito.internal.configuration.plugins.Plugins; import org.mockito.internal.junit.JUnitRule; import org.mockito.internal.junit.VerificationCollectorImpl; +import org.mockito.internal.util.ConsoleMockitoLogger; import org.mockito.quality.Strictness; /** @@ -30,7 +30,7 @@ public class MockitoJUnit { * @since 1.10.17 */ public static MockitoRule rule() { - return new JUnitRule(Plugins.getMockitoLogger(), Strictness.WARN); + return new JUnitRule(new ConsoleMockitoLogger(), Strictness.WARN); } /** diff --git a/src/main/java/org/mockito/listeners/StubbingLookupEvent.java b/src/main/java/org/mockito/listeners/StubbingLookupEvent.java deleted file mode 100644 index a03fb59..0000000 --- a/src/main/java/org/mockito/listeners/StubbingLookupEvent.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2018 Mockito contributors - * This program is made available under the terms of the MIT License. - */ -package org.mockito.listeners; - -import org.mockito.invocation.Invocation; -import org.mockito.mock.MockCreationSettings; -import org.mockito.stubbing.Stubbing; - -import java.util.Collection; - -/** - * Represent an information about the looked up stubbing - * - * @since 2.24.6 - */ -public interface StubbingLookupEvent { - - /** - * @return The invocation that causes stubbing lookup - * @since 2.24.6 - */ - Invocation getInvocation(); - - /** - * @return Looked up stubbing. It can be <code>null</code>, which indicates that the invocation was not stubbed - * @since 2.24.6 - */ - Stubbing getStubbingFound(); - - /** - * @return All stubbings declared on the mock object that we are invoking - * @since 2.24.6 - */ - Collection<Stubbing> getAllStubbings(); - - /** - * @return Settings of the mock object that we are invoking - * @since 2.24.6 - */ - MockCreationSettings getMockSettings(); -} diff --git a/src/main/java/org/mockito/listeners/StubbingLookupListener.java b/src/main/java/org/mockito/listeners/StubbingLookupListener.java deleted file mode 100644 index b33e063..0000000 --- a/src/main/java/org/mockito/listeners/StubbingLookupListener.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.mockito.listeners; - -import org.mockito.MockSettings; -import org.mockito.mock.MockCreationSettings; - -/** - * When a method is called on a mock object Mockito looks up any stubbings recorded on that mock. - * This listener gets notified on stubbing lookup. - * Register listener via {@link MockSettings#stubbingLookupListeners(StubbingLookupListener...)}. - * This API is used by Mockito to implement {@link org.mockito.exceptions.misusing.PotentialStubbingProblem} - * (part of Mockito {@link org.mockito.quality.Strictness}). - * <p> - * Details: When method is called on the mock object, Mockito looks for any answer (stubbing) declared on that mock. - * If the stubbed answer is found, that answer is then invoked (value returned, thrown exception, etc.). - * If the answer is not found (e.g. that invocation was not stubbed on the mock), mock's default answer is used. - * This listener implementation is notified when Mockito attempts to find an answer for invocation on a mock. - * <p> - * The listeners can be accessed via {@link MockCreationSettings#getStubbingLookupListeners()}. - * - * @since 2.24.6 - */ -public interface StubbingLookupListener { - - /** - * Called by the framework when Mockito looked up an answer for invocation on a mock. - * For details, see {@link StubbingLookupListener}. - * - * @param stubbingLookupEvent - Information about the looked up stubbing - * @since 2.24.6 - */ - void onStubbingLookup(StubbingLookupEvent stubbingLookupEvent); -} diff --git a/src/main/java/org/mockito/mock/MockCreationSettings.java b/src/main/java/org/mockito/mock/MockCreationSettings.java index 2343b0d..7e74be8 100644 --- a/src/main/java/org/mockito/mock/MockCreationSettings.java +++ b/src/main/java/org/mockito/mock/MockCreationSettings.java @@ -9,7 +9,6 @@ import org.mockito.Incubating; import org.mockito.MockSettings; import org.mockito.NotExtensible; import org.mockito.listeners.InvocationListener; -import org.mockito.listeners.StubbingLookupListener; import org.mockito.listeners.VerificationStartedListener; import org.mockito.quality.Strictness; import org.mockito.stubbing.Answer; @@ -71,17 +70,7 @@ public interface MockCreationSettings<T> { boolean isStripAnnotations(); /** - * Returns {@link StubbingLookupListener} instances attached to this mock via {@link MockSettings#stubbingLookupListeners(StubbingLookupListener...)}. - * The resulting list is mutable, you can add/remove listeners even after the mock was created. - * <p> - * For more details see {@link StubbingLookupListener}. - * - * @since 2.24.6 - */ - List<StubbingLookupListener> getStubbingLookupListeners(); - - /** - * {@link InvocationListener} instances attached to this mock, see {@link org.mockito.MockSettings#invocationListeners(InvocationListener...)}. + * {@link InvocationListener} instances attached to this mock, see {@link org.mockito.MockSettings#invocationListeners}. */ List<InvocationListener> getInvocationListeners(); diff --git a/src/main/java/org/mockito/plugins/InlineMockMaker.java b/src/main/java/org/mockito/plugins/InlineMockMaker.java deleted file mode 100644 index 8771aa7..0000000 --- a/src/main/java/org/mockito/plugins/InlineMockMaker.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2019 Mockito contributors - * This program is made available under the terms of the MIT License. - */ - -package org.mockito.plugins; - -import org.mockito.Incubating; -import org.mockito.MockitoFramework; - -/** - * Extension to {@link MockMaker} for mock makers that changes inline method implementations - * and need keep track of created mock objects. - * <p> - * Mockito's default inline mock maker keeps track of created mock objects via weak reference map. - * This poses a risk of memory leaks in certain scenarios - * (issue <a href="https://github.com/mockito/mockito/pull/1619">#1619</a>). - * There is no clean way to tackle those problems at the moment. - * Hence, {@code InlineMockMaker} interface exposes methods to explicitly clear mock references. - * Those methods are called by {@link MockitoFramework#clearInlineMocks()}. - * When the user encounters a leak, he can mitigate the problem with {@link MockitoFramework#clearInlineMocks()}. - * <p> - * {@code InlineMockMaker} is for expert users and framework integrators, when custom inline mock maker is in use. - * If you have a custom {@link MockMaker} that keeps track of mock objects, - * please have your mock maker implement {@code InlineMockMaker} interface. - * This way, it can participate in {@link MockitoFramework#clearInlineMocks()} API. - * - * @since 2.25.0 - */ -@Incubating -public interface InlineMockMaker extends MockMaker { - - /** - * Clean up internal state for specified {@code mock}. You may assume there won't be any interaction to the specific - * mock after this is called. - * - * @param mock the mock instance whose internal state is to be cleaned. - * @since 2.25.0 - */ - @Incubating - void clearMock(Object mock); - - /** - * Cleans up internal state for all existing mocks. You may assume there won't be any interaction to mocks created - * previously after this is called. - * - * @since 2.25.0 - */ - @Incubating - void clearAllMocks(); - -} diff --git a/src/main/java/org/mockito/plugins/MockitoLogger.java b/src/main/java/org/mockito/plugins/MockitoLogger.java deleted file mode 100644 index 38ca4a8..0000000 --- a/src/main/java/org/mockito/plugins/MockitoLogger.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2007 Mockito contributors - * This program is made available under the terms of the MIT License. - */ -package org.mockito.plugins; - -import org.mockito.Incubating; - -/** - * Mockito logger. - * - * <p>By default logs to console</p> - * - * <p>All mockito logging goes through this class and could be customized as usual Mockito plugin.</p> - * - * <h3>Using the extension point</h3> - * - * <p>Suppose you wrote an extension to customize logging, in order to tell Mockito to use it you need to put - * in your <strong>classpath</strong>: - * <ol style="list-style-type: lower-alpha"> - * <li> - * The implementation itself, for example <code>org.awesome.mockito.AwesomeLogger</code> that - * extends the <code>MockitoLogger</code>. - * </li> - * <li> - * A file "<code>mockito-extensions/org.mockito.plugins.MockitoLogger</code>". The content of this file is - * exactly a <strong>one</strong> line with the qualified name: - * <code>org.awesome.mockito.AwesomeLogger</code>. - * </li> - * </ol> - * </p> - * - * <p>Note that if several <code>mockito-extensions/org.mockito.plugins.MockitoLogger</code> files exists in the - * classpath Mockito will only use the first returned by the standard {@link ClassLoader#getResource} mechanism. - * - * @since 2.23.19 - */ -@Incubating -public interface MockitoLogger { - /** - * Log specified object. - * - * @param what to be logged - */ - @Incubating - void log(Object what); -} diff --git a/src/main/java/org/mockito/runners/ConsoleSpammingMockitoJUnitRunner.java b/src/main/java/org/mockito/runners/ConsoleSpammingMockitoJUnitRunner.java index b03b098..522b795 100644 --- a/src/main/java/org/mockito/runners/ConsoleSpammingMockitoJUnitRunner.java +++ b/src/main/java/org/mockito/runners/ConsoleSpammingMockitoJUnitRunner.java @@ -12,11 +12,11 @@ import org.junit.runner.manipulation.NoTestsRemainException; import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunListener; import org.junit.runner.notification.RunNotifier; -import org.mockito.internal.configuration.plugins.Plugins; import org.mockito.internal.debugging.WarningsCollector; import org.mockito.internal.runners.RunnerFactory; import org.mockito.internal.runners.InternalRunner; -import org.mockito.plugins.MockitoLogger; +import org.mockito.internal.util.ConsoleMockitoLogger; +import org.mockito.internal.util.MockitoLogger; import java.lang.reflect.InvocationTargetException; @@ -33,7 +33,7 @@ public class ConsoleSpammingMockitoJUnitRunner extends Runner implements Filtera private final InternalRunner runner; public ConsoleSpammingMockitoJUnitRunner(Class<?> klass) throws InvocationTargetException { - this(Plugins.getMockitoLogger(), new RunnerFactory().create(klass)); + this(new ConsoleMockitoLogger(), new RunnerFactory().create(klass)); } ConsoleSpammingMockitoJUnitRunner(MockitoLogger logger, InternalRunner runner) { diff --git a/src/main/java/org/mockito/session/MockitoSessionBuilder.java b/src/main/java/org/mockito/session/MockitoSessionBuilder.java index b17cfe7..b3a758b 100644 --- a/src/main/java/org/mockito/session/MockitoSessionBuilder.java +++ b/src/main/java/org/mockito/session/MockitoSessionBuilder.java @@ -7,7 +7,6 @@ package org.mockito.session; import org.mockito.Incubating; import org.mockito.MockitoAnnotations; import org.mockito.MockitoSession; -import org.mockito.NotExtensible; import org.mockito.exceptions.misusing.UnfinishedMockingSessionException; import org.mockito.quality.Strictness; @@ -18,7 +17,6 @@ import org.mockito.quality.Strictness; * @since 2.7.0 */ @Incubating -@NotExtensible public interface MockitoSessionBuilder { /** diff --git a/src/main/java/org/mockito/session/MockitoSessionLogger.java b/src/main/java/org/mockito/session/MockitoSessionLogger.java index f876433..e5f40ad 100644 --- a/src/main/java/org/mockito/session/MockitoSessionLogger.java +++ b/src/main/java/org/mockito/session/MockitoSessionLogger.java @@ -6,7 +6,6 @@ package org.mockito.session; import org.mockito.Incubating; import org.mockito.MockitoSession; -import org.mockito.NotExtensible; /** * Logger for {@linkplain org.mockito.quality.MockitoHint hints} emitted when @@ -18,7 +17,6 @@ import org.mockito.NotExtensible; * @since 2.15.0 */ @Incubating -@NotExtensible public interface MockitoSessionLogger { /** diff --git a/src/main/java/org/mockito/stubbing/Answer6.java b/src/main/java/org/mockito/stubbing/Answer6.java deleted file mode 100644 index bf668cf..0000000 --- a/src/main/java/org/mockito/stubbing/Answer6.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2016 Mockito contributors - * This program is made available under the terms of the MIT License. - */ -package org.mockito.stubbing; - -import org.mockito.Incubating; - -/** - * Generic interface to be used for configuring mock's answer for a six argument invocation. - * - * Answer specifies an action that is executed and a return value that is returned when you interact with the mock. - * <p> - * Example of stubbing a mock with this custom answer: - * - * <pre class="code"><code class="java"> - * import static org.mockito.AdditionalAnswers.answer; - * - * when(mock.someMethod(anyInt(), anyString(), anyChar(), any(), any(), anyBoolean())).then(answer( - * new Answer6<StringBuilder, Integer, String, Character, Object, Object, Boolean>() { - * public StringBuilder answer(Integer i, String s, Character c, Object o1, Object o2, Boolean isIt) { - * return new StringBuilder().append(i).append(s).append(c).append(o1.hashCode()).append(o2.hashCode()).append(isIt); - * } - * })); - * - * //Following will print a string like "3xyz131635550true" - * System.out.println(mock.someMethod(3, "xy", 'z', new Object(), new Object(), true)); - * </code></pre> - * - * @param <T> return type - * @param <A0> type of the first argument - * @param <A1> type of the second argument - * @param <A2> type of the third argument - * @param <A3> type of the fourth argument - * @param <A4> type of the fifth argument - * @param <A5> type of the sixth argument - * @see Answer - */ -@Incubating -public interface Answer6<T, A0, A1, A2, A3, A4, A5> { - /** - * @param argument0 the first argument. - * @param argument1 the second argument. - * @param argument2 the third argument. - * @param argument3 the fourth argument. - * @param argument4 the fifth argument. - * @param argument5 the sixth argument. - * - * @return the value to be returned. - * - * @throws Throwable the throwable to be thrown - */ - T answer( A0 argument0, A1 argument1, A2 argument2, A3 argument3, A4 argument4, A5 argument5 ) throws Throwable; -} diff --git a/src/main/java/org/mockito/stubbing/VoidAnswer6.java b/src/main/java/org/mockito/stubbing/VoidAnswer6.java deleted file mode 100644 index 5df66a3..0000000 --- a/src/main/java/org/mockito/stubbing/VoidAnswer6.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2016 Mockito contributors - * This program is made available under the terms of the MIT License. - */ -package org.mockito.stubbing; - -import org.mockito.Incubating; - -/** - * Generic interface to be used for configuring mock's answer for a six argument invocation that returns nothing. - * - * Answer specifies an action that is executed when you interact with the mock. - * <p> - * Example of stubbing a mock with this custom answer: - * - * <pre class="code"><code class="java"> - * import static org.mockito.AdditionalAnswers.answerVoid; - * - * doAnswer(answerVoid( - * new VoidAnswer5<String, Integer, String, Character, Object, String>() { - * public void answer(String msg, Integer count, String another, Character c, Object o, String subject) throws Exception { - * throw new Exception(String.format(msg, another, c, o, count, subject)); - * } - * })).when(mock).someMethod(anyString(), anyInt(), anyString(), anyChar(), any(), anyString()); - * - * // The following will raise an exception with the message "ka-boom <3 mockito" - * mock.someMethod("%s-boom %c%d %s", 3, "ka", '<', new Object(), "mockito"); - * </code></pre> - * - * @param <A0> type of the first argument - * @param <A1> type of the second argument - * @param <A2> type of the third argument - * @param <A3> type of the fourth argument - * @param <A4> type of the fifth argument - * @param <A5> type of the sixth argument - * @see Answer - */ -@Incubating -public interface VoidAnswer6<A0, A1, A2, A3, A4, A5> { - /** - * @param argument0 the first argument. - * @param argument1 the second argument. - * @param argument2 the third argument. - * @param argument3 the fourth argument. - * @param argument4 the fifth argument. - * @param argument5 the sixth argument. - * - * @throws Throwable the throwable to be thrown - */ - void answer(A0 argument0, A1 argument1, A2 argument2, A3 argument3, A4 argument4, A5 argument5) throws Throwable; -} |