Merge changes from topic 'upgrade-mockito-1.10.19-dexmaker-1.3'
am: e34cba15c1
Change-Id: I83144638c2fe3faabccf41972a9b42da12478458
diff --git a/Android.mk b/Android.mk
index ddceaea..d9bf34c 100644
--- a/Android.mk
+++ b/Android.mk
@@ -68,7 +68,7 @@
LOCAL_SRC_FILES := $(target_src_files)
LOCAL_JAVA_LIBRARIES := junit4-target objenesis-target
LOCAL_MODULE := mockito-api
-LOCAL_SDK_VERSION := 10
+LOCAL_SDK_VERSION := 16
LOCAL_MODULE_TAGS := optional
include $(BUILD_STATIC_JAVA_LIBRARY)
@@ -78,7 +78,7 @@
LOCAL_MODULE := mockito-target
LOCAL_STATIC_JAVA_LIBRARIES := mockito-target-minus-junit4 junit4-target
-LOCAL_SDK_VERSION := 10
+LOCAL_SDK_VERSION := 16
LOCAL_MODULE_TAGS := optional
include $(BUILD_STATIC_JAVA_LIBRARY)
@@ -89,7 +89,7 @@
LOCAL_MODULE := mockito-target-minus-junit4
LOCAL_STATIC_JAVA_LIBRARIES := mockito-api dexmaker dexmaker-mockmaker objenesis-target
LOCAL_JAVA_LIBRARIES := junit4-target
-LOCAL_SDK_VERSION := 10
+LOCAL_SDK_VERSION := 16
LOCAL_MODULE_TAGS := optional
LOCAL_JAVA_LANGUAGE_VERSION := 1.7
include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/README.android b/README.android
index 7710b00..db40633 100644
--- a/README.android
+++ b/README.android
@@ -1,8 +1,14 @@
-Mockito is a mocking framework with a clean and simple API.
-See https://code.google.com/p/mockito/ for more information.
+URL: https://github.com/mockito/mockito
+Version: v1.10.19
+License: Apache 2.0
+Description: Mockito is a mocking framework with a clean and simple API.
For Android, we need to combine Mockito with a MockMaker provided by the
Dexmaker module.
The source can be updated using the update_source.sh script.
+Local Modifications:
+ Fixed some generic/casting issues probably caused by stricter compiler.
+ Fixed compiler failure caused by upstream mismatch between the cglib-and-asm
+ source and prebuilt library.
diff --git a/cglib-and-asm/.gitignore b/cglib-and-asm/.gitignore
new file mode 100644
index 0000000..f2e671b
--- /dev/null
+++ b/cglib-and-asm/.gitignore
@@ -0,0 +1 @@
+/build-eclipse/
diff --git a/cglib-and-asm/README.TXT b/cglib-and-asm/README.TXT
index 5a0092c..82180d7 100644
--- a/cglib-and-asm/README.TXT
+++ b/cglib-and-asm/README.TXT
@@ -2,7 +2,4 @@
Unfortunately, jarjar was not able to repackage sources
therefore I'm using this subproject to repackage cglib+asm.
-We should NEVER modify cglib/asm - sources are here only for the sake of repackaging.
-
-Source was obtained from https://github.com/mockito/mockito/tree/master/cglib-and-asm and cglib+asm
-has been included in the Mockito builds since 2008 in Mockito 1.5.
+We should NEVER modify cglib/asm - sources are here only for the sake of repackaging.
\ No newline at end of file
diff --git a/src/org/mockito/AdditionalAnswers.java b/src/org/mockito/AdditionalAnswers.java
index f576f40..b184928 100644
--- a/src/org/mockito/AdditionalAnswers.java
+++ b/src/org/mockito/AdditionalAnswers.java
@@ -99,7 +99,8 @@
* doAnswer(returnsArgAt(3)).when(person).remember(dream1, dream2, dream3, dream4)</code></pre>
*
* @param <T> Return type of the invocation.
- * @return Answer that will return the second argument of the invocation.
+ * @param position index of the argument from the list of arguments.
+ * @return Answer that will return the argument from the given position in the argument's list
*
* @since 1.9.5
*/
@@ -108,7 +109,8 @@
}
/**
- * An answer that directly forwards the calls to the delegate.
+ * An answer that directly forwards the calls to the delegate. The delegate may or may not be of the same type as the mock.
+ * If the type is different, a matching method needs to be found on delegate type otherwise an exception is thrown.
* <p>
* Useful for spies or partial mocks of objects that are difficult to mock
* or spy using the usual spy API. Possible use cases:
@@ -162,7 +164,9 @@
* doReturn("foo").when(listWithDelegate).get(0);
* </code></pre>
*
- * @param delegate The delegate to forward calls to.
+ * @param delegate The delegate to forward calls to. It does not have to be of the same type as the mock (although it usually is).
+ * The only requirement is that the instance should have compatible method signatures including the return values.
+ * Only the methods that were actually executed on the mock need to be present on the delegate type.
* @return the answer
*
* @since 1.9.5
diff --git a/src/org/mockito/AdditionalMatchers.java b/src/org/mockito/AdditionalMatchers.java
index c0a297f..f5b7606 100644
--- a/src/org/mockito/AdditionalMatchers.java
+++ b/src/org/mockito/AdditionalMatchers.java
@@ -41,7 +41,7 @@
*/
public class AdditionalMatchers {
- private static MockingProgress mockingProgress = new ThreadSafeMockingProgress();
+ private static final MockingProgress MOCKING_PROGRESS = new ThreadSafeMockingProgress();
/**
* argument greater than or equal the given value.
@@ -573,7 +573,7 @@
* @return <code>false</code>.
*/
public static boolean and(boolean first, boolean second) {
- return mockingProgress.getArgumentMatcherStorage().reportAnd().returnFalse();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportAnd().returnFalse();
}
/**
@@ -588,7 +588,7 @@
* @return <code>0</code>.
*/
public static byte and(byte first, byte second) {
- return mockingProgress.getArgumentMatcherStorage().reportAnd().returnZero();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportAnd().returnZero();
}
/**
@@ -603,7 +603,7 @@
* @return <code>0</code>.
*/
public static char and(char first, char second) {
- return mockingProgress.getArgumentMatcherStorage().reportAnd().returnChar();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportAnd().returnChar();
}
/**
@@ -618,7 +618,7 @@
* @return <code>0</code>.
*/
public static double and(double first, double second) {
- return mockingProgress.getArgumentMatcherStorage().reportAnd().returnZero();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportAnd().returnZero();
}
/**
@@ -633,7 +633,7 @@
* @return <code>0</code>.
*/
public static float and(float first, float second) {
- return mockingProgress.getArgumentMatcherStorage().reportAnd().returnZero();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportAnd().returnZero();
}
/**
@@ -648,7 +648,7 @@
* @return <code>0</code>.
*/
public static int and(int first, int second) {
- return mockingProgress.getArgumentMatcherStorage().reportAnd().returnZero();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportAnd().returnZero();
}
/**
@@ -663,7 +663,7 @@
* @return <code>0</code>.
*/
public static long and(long first, long second) {
- return mockingProgress.getArgumentMatcherStorage().reportAnd().returnZero();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportAnd().returnZero();
}
/**
@@ -678,7 +678,7 @@
* @return <code>0</code>.
*/
public static short and(short first, short second) {
- return mockingProgress.getArgumentMatcherStorage().reportAnd().returnZero();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportAnd().returnZero();
}
/**
@@ -695,7 +695,7 @@
* @return <code>null</code>.
*/
public static <T> T and(T first, T second) {
- return mockingProgress.getArgumentMatcherStorage().reportAnd().<T>returnNull();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportAnd().<T>returnNull();
}
/**
@@ -710,7 +710,7 @@
* @return <code>false</code>.
*/
public static boolean or(boolean first, boolean second) {
- return mockingProgress.getArgumentMatcherStorage().reportOr().returnFalse();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportOr().returnFalse();
}
/**
@@ -727,7 +727,7 @@
* @return <code>null</code>.
*/
public static <T> T or(T first, T second) {
- return mockingProgress.getArgumentMatcherStorage().reportOr().<T>returnNull();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportOr().<T>returnNull();
}
/**
@@ -742,7 +742,7 @@
* @return <code>0</code>.
*/
public static short or(short first, short second) {
- return mockingProgress.getArgumentMatcherStorage().reportOr().returnZero();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportOr().returnZero();
}
/**
@@ -757,7 +757,7 @@
* @return <code>0</code>.
*/
public static long or(long first, long second) {
- return mockingProgress.getArgumentMatcherStorage().reportOr().returnZero();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportOr().returnZero();
}
/**
@@ -772,7 +772,7 @@
* @return <code>0</code>.
*/
public static int or(int first, int second) {
- return mockingProgress.getArgumentMatcherStorage().reportOr().returnZero();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportOr().returnZero();
}
/**
@@ -787,7 +787,7 @@
* @return <code>0</code>.
*/
public static float or(float first, float second) {
- return mockingProgress.getArgumentMatcherStorage().reportOr().returnZero();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportOr().returnZero();
}
/**
@@ -802,7 +802,7 @@
* @return <code>0</code>.
*/
public static double or(double first, double second) {
- return mockingProgress.getArgumentMatcherStorage().reportOr().returnZero();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportOr().returnZero();
}
/**
@@ -817,7 +817,7 @@
* @return <code>0</code>.
*/
public static char or(char first, char second) {
- return mockingProgress.getArgumentMatcherStorage().reportOr().returnChar();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportOr().returnChar();
}
/**
@@ -832,7 +832,7 @@
* @return <code>0</code>.
*/
public static byte or(byte first, byte second) {
- return mockingProgress.getArgumentMatcherStorage().reportOr().returnZero();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportOr().returnZero();
}
/**
@@ -847,7 +847,7 @@
* @return <code>null</code>.
*/
public static <T> T not(T first) {
- return mockingProgress.getArgumentMatcherStorage().reportNot().<T>returnNull();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportNot().<T>returnNull();
}
/**
@@ -860,7 +860,7 @@
* @return <code>0</code>.
*/
public static short not(short first) {
- return mockingProgress.getArgumentMatcherStorage().reportNot().returnZero();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportNot().returnZero();
}
/**
@@ -873,7 +873,7 @@
* @return <code>0</code>.
*/
public static int not(int first) {
- return mockingProgress.getArgumentMatcherStorage().reportNot().returnZero();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportNot().returnZero();
}
/**
@@ -886,7 +886,7 @@
* @return <code>0</code>.
*/
public static long not(long first) {
- return mockingProgress.getArgumentMatcherStorage().reportNot().returnZero();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportNot().returnZero();
}
/**
@@ -899,7 +899,7 @@
* @return <code>0</code>.
*/
public static float not(float first) {
- return mockingProgress.getArgumentMatcherStorage().reportNot().returnZero();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportNot().returnZero();
}
/**
@@ -912,7 +912,7 @@
* @return <code>0</code>.
*/
public static double not(double first) {
- return mockingProgress.getArgumentMatcherStorage().reportNot().returnZero();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportNot().returnZero();
}
/**
@@ -925,7 +925,7 @@
* @return <code>0</code>.
*/
public static char not(char first) {
- return mockingProgress.getArgumentMatcherStorage().reportNot().returnChar();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportNot().returnChar();
}
/**
@@ -938,7 +938,7 @@
* @return <code>false</code>.
*/
public static boolean not(boolean first) {
- return mockingProgress.getArgumentMatcherStorage().reportNot().returnFalse();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportNot().returnFalse();
}
/**
@@ -951,7 +951,7 @@
* @return <code>0</code>.
*/
public static byte not(byte first) {
- return mockingProgress.getArgumentMatcherStorage().reportNot().returnZero();
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportNot().returnZero();
}
/**
@@ -987,6 +987,6 @@
}
private static HandyReturnValues reportMatcher(ArgumentMatcher<?> matcher) {
- return mockingProgress.getArgumentMatcherStorage().reportMatcher(matcher);
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportMatcher(matcher);
}
}
\ No newline at end of file
diff --git a/src/org/mockito/Answers.java b/src/org/mockito/Answers.java
index 7da30d1..32d566f 100644
--- a/src/org/mockito/Answers.java
+++ b/src/org/mockito/Answers.java
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito;
import org.mockito.internal.stubbing.answers.CallsRealMethods;
@@ -71,7 +71,7 @@
CALLS_REAL_METHODS(new CallsRealMethods())
;
- private Answer<Object> implementation;
+ private final Answer<Object> implementation;
private Answers(Answer<Object> implementation) {
this.implementation = implementation;
diff --git a/src/org/mockito/ArgumentCaptor.java b/src/org/mockito/ArgumentCaptor.java
index 808e441..0efe061 100644
--- a/src/org/mockito/ArgumentCaptor.java
+++ b/src/org/mockito/ArgumentCaptor.java
@@ -5,7 +5,6 @@
package org.mockito;
import org.mockito.internal.matchers.CapturingMatcher;
-import org.mockito.internal.matchers.VarargCapturingMatcher;
import org.mockito.internal.progress.HandyReturnValues;
import java.util.List;
@@ -24,6 +23,15 @@
* assertEquals("John", argument.getValue().getName());
* </code></pre>
*
+ * Example of capturing varargs:
+ * <pre class="code"><code class="java">
+ * //capturing varargs:
+ * ArgumentCaptor<Person> varArgs = ArgumentCaptor.forClass(Person.class);
+ * verify(mock).varArgMethod(varArgs.capture());
+ * List expected = asList(new Person("John"), new Person("Jane"));
+ * assertEquals(expected, varArgs.getAllValues());
+ * </code></pre>
+ *
* <p>
* <strong>Warning:</strong> it is recommended to use ArgumentCaptor with verification <strong>but not</strong> with stubbing.
* Using ArgumentCaptor with stubbing may decrease test readability because captor is created outside of assert (aka verify or 'then') block.
@@ -57,7 +65,6 @@
HandyReturnValues handyReturnValues = new HandyReturnValues();
private final CapturingMatcher<T> capturingMatcher = new CapturingMatcher<T>();
- private final VarargCapturingMatcher<T> varargCapturingMatcher = new VarargCapturingMatcher<T>();
private final Class<T> clazz;
/**
@@ -100,25 +107,9 @@
}
/**
- * Use it to capture the variable arguments. This method <b>must be used inside of verification</b>.
+ * Returns the captured value of the argument. When capturing varargs use {@link #getAllValues()}.
* <p>
- * Internally, this method registers a special implementation of an {@link ArgumentMatcher}.
- * This argument matcher stores the variable arguments values so that you can use it later to perform assertions.
- * <p>
- * See examples in javadoc for {@link ArgumentCaptor} class.
- *
- * @return null or default values
- */
- public T captureVararg() {
- Mockito.argThat(varargCapturingMatcher);
- return handyReturnValues.returnFor(clazz);
- }
-
-
- /**
- * Returns the captured value of the argument.
- * <p>
- * If the method was called multiple times then it returns the latest captured value.
+ * If verified method was called multiple times then this method it returns the latest captured value.
* <p>
* See examples in javadoc for {@link ArgumentCaptor} class.
*
@@ -129,29 +120,32 @@
}
/**
- * Returns the captured value of the variable arguments.
- * <p>
- * If the method was called multiple times then it returns the latest captured variable arguments.
- * <p>
- * See examples in javadoc for {@link ArgumentCaptor} class.
- *
- * @return captured varargs
- */
- public List<T> getVarargsValues() {
- return this.varargCapturingMatcher.getLastVarargs();
- }
-
- /**
- * Returns all captured values. Use it in case the verified method was called multiple times.
+ * Returns all captured values. Use it when capturing varargs or when the verified method was called multiple times.
+ * When varargs method was called multiple times, this method returns merged list of all values from all invocations.
* <p>
* Example:
* <pre class="code"><code class="java">
+ * mock.doSomething(new Person("John");
+ * mock.doSomething(new Person("Jane");
+ *
* ArgumentCaptor<Person> peopleCaptor = ArgumentCaptor.forClass(Person.class);
* verify(mock, times(2)).doSomething(peopleCaptor.capture());
*
* List<Person> capturedPeople = peopleCaptor.getAllValues();
* assertEquals("John", capturedPeople.get(0).getName());
* assertEquals("Jane", capturedPeople.get(1).getName());
+ * </pre>
+ *
+ * Example of capturing varargs:
+ * <pre class="code"><code class="java">
+ * mock.countPeople(new Person("John"), new Person("Jane"); //vararg method
+ *
+ * ArgumentCaptor<Person> peopleCaptor = ArgumentCaptor.forClass(Person.class);
+ *
+ * verify(mock).countPeople(peopleCaptor.capture());
+ *
+ * List expected = asList(new Person("John"), new Person("Jane"));
+ * assertEquals(expected, peopleCaptor.getAllValues());
* </code></pre>
* See more examples in javadoc for {@link ArgumentCaptor} class.
*
@@ -162,26 +156,6 @@
}
/**
- * Returns all captured variable arguments. Use it in case the verified method was called multiple times.
- * <p>
- * Example:
- * <pre class="code"><code class="java">
- * ArgumentCaptor<Person> peopleFornamesCaptor = ArgumentCaptor.forClass(String.class);
- * verify(mock, times(2)).doSomething(peopleFornamesCaptor.captureVarargs());
- *
- * List<String> peopleFornames = peopleFornamesCaptor.getAllVarargs();
- * assertThat(peopleFornames.get(0)).contains("John", "Carl");
- * assertThat(peopleFornames.get(1)).contains("Janes", "Eloise", "Lois");
- * </code></pre>
- * See more examples in javadoc for {@link ArgumentCaptor} class.
- *
- * @return all captured varargs
- */
- public List<List<T>> getAllVarargsValues() {
- return this.varargCapturingMatcher.getAllVarargs();
- }
-
- /**
* Build a new <code>ArgumentCaptor</code>.
* <p>
* Note that an <code>ArgumentCaptor</code> <b>*don't do any type checks*</b>, it is only there to avoid casting
diff --git a/src/org/mockito/BDDMockito.java b/src/org/mockito/BDDMockito.java
index ec05bb7..b1b5e5d 100644
--- a/src/org/mockito/BDDMockito.java
+++ b/src/org/mockito/BDDMockito.java
@@ -1,12 +1,13 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito;
import org.mockito.stubbing.Answer;
import org.mockito.stubbing.OngoingStubbing;
import org.mockito.stubbing.Stubber;
+import org.mockito.verification.VerificationMode;
/**
* Behavior Driven Development style of writing tests uses <b>//given //when //then</b> comments as fundamental parts of your test methods.
@@ -15,54 +16,62 @@
* Start learning about BDD here: <a href="http://en.wikipedia.org/wiki/Behavior_Driven_Development">http://en.wikipedia.org/wiki/Behavior_Driven_Development</a>
* <p>
* The problem is that current stubbing api with canonical role of <b>when</b> word does not integrate nicely with <b>//given //when //then</b> comments.
- * It's because stubbing belongs to <b>given</b> component of the test and not to the <b>when</b> component of the test.
- * Hence {@link BDDMockito} class introduces an alias so that you stub method calls with {@link BDDMockito#given(Object)} method.
- * Now it really nicely integrates with the <b>given</b> component of a BDD style test!
+ * It's because stubbing belongs to <b>given</b> component of the test and not to the <b>when</b> component of the test.
+ * Hence {@link BDDMockito} class introduces an alias so that you stub method calls with {@link BDDMockito#given(Object)} method.
+ * Now it really nicely integrates with the <b>given</b> component of a BDD style test!
* <p>
- * Here is how the test might look like:
+ * Here is how the test might look like:
* <pre class="code"><code class="java">
* import static org.mockito.BDDMockito.*;
- *
+ *
* Seller seller = mock(Seller.class);
* Shop shop = new Shop(seller);
- *
+ *
* public void shouldBuyBread() throws Exception {
- * //given
+ * //given
* given(seller.askForBread()).willReturn(new Bread());
- *
+ *
* //when
* Goods goods = shop.buyBread();
- *
+ *
* //then
* assertThat(goods, containBread());
- * }
+ * }
* </code></pre>
- *
+ *
* Stubbing voids with throwables:
* <pre class="code"><code class="java">
* //given
* willThrow(new RuntimeException("boo")).given(mock).foo();
- *
+ *
* //when
* Result result = systemUnderTest.perform();
- *
+ *
* //then
* assertEquals(failure, result);
* </code></pre>
* <p>
+ * For BDD style mock verification take a look at {@link Then} in action:
+ * <pre class="code"><code class="java">
+ * person.ride(bike);
+ * person.ride(bike);
+ *
+ * then(person).should(times(2)).ride(bike);
+ * </code></pre>
+ *
* One of the purposes of BDDMockito is also to show how to tailor the mocking syntax to a different programming style.
*
* @since 1.8.0
*/
@SuppressWarnings("unchecked")
public class BDDMockito extends Mockito {
-
+
/**
* See original {@link OngoingStubbing}
* @since 1.8.0
*/
- public static interface BDDMyOngoingStubbing<T> {
-
+ public interface BDDMyOngoingStubbing<T> {
+
/**
* See original {@link OngoingStubbing#thenAnswer(Answer)}
* @since 1.8.0
@@ -111,7 +120,11 @@
*/
<M> M getMock();
}
-
+
+ /**
+ * @deprecated not part of the public API, use {@link BDDMyOngoingStubbing} instead.
+ */
+ @Deprecated
public static class BDDOngoingStubbingImpl<T> implements BDDMyOngoingStubbing<T> {
private final OngoingStubbing<T> mockitoOngoingStubbing;
@@ -169,7 +182,7 @@
return (M) mockitoOngoingStubbing.getMock();
}
}
-
+
/**
* see original {@link Mockito#when(Object)}
* @since 1.8.0
@@ -177,30 +190,95 @@
public static <T> BDDMyOngoingStubbing<T> given(T methodCall) {
return new BDDOngoingStubbingImpl<T>(Mockito.when(methodCall));
}
-
+
+ /**
+ * Bdd style verification of mock behavior.
+ *
+ * <pre class="code"><code class="java">
+ * person.ride(bike);
+ * person.ride(bike);
+ *
+ * then(person).should(times(2)).ride(bike);
+ * </code></pre>
+ *
+ * @see #verify(Object)
+ * @see #verify(Object, VerificationMode)
+ * @since 1.10.0
+ */
+ public static <T> Then<T> then(T mock) {
+ return new ThenImpl<T>(mock);
+ }
+
+ /**
+ * Provides fluent way of mock verification.
+ *
+ * @param <T> type of the mock
+ *
+ * @since 1.10.5
+ */
+ public static interface Then<T> {
+
+ /**
+ * @see #verify(Object)
+ * @since 1.10.5
+ */
+ T should();
+
+ /**
+ * @see #verify(Object, VerificationMode)
+ * @since 1.10.5
+ */
+ T should(VerificationMode mode);
+ }
+
+ static class ThenImpl<T> implements Then<T> {
+
+ private final T mock;
+
+ ThenImpl(T mock) {
+ this.mock = mock;
+ }
+
+ /**
+ * @see #verify(Object)
+ * @since 1.10.5
+ */
+ public T should() {
+ return verify(mock);
+ }
+
+ /**
+ * @see #verify(Object, VerificationMode)
+ * @since 1.10.5
+ */
+ public T should(VerificationMode mode) {
+ return verify(mock, mode);
+ }
+ }
+
/**
* See original {@link Stubber}
* @since 1.8.0
*/
- public static interface BDDStubber {
+ public interface BDDStubber {
/**
* See original {@link Stubber#doAnswer(Answer)}
* @since 1.8.0
*/
BDDStubber willAnswer(Answer answer);
-
+
/**
* See original {@link Stubber#doNothing()}
* @since 1.8.0
*/
BDDStubber willNothing();
-
+
/**
* See original {@link Stubber#doReturn(Object)}
* @since 1.8.0
*/
BDDStubber willReturn(Object toBeReturned);
-
+
/**
* See original {@link Stubber#doThrow(Throwable)}
* @since 1.8.0
@@ -225,7 +303,11 @@
*/
<T> T given(T mock);
}
-
+
+ /**
+ * @deprecated not part of the public API, use {@link BDDStubber} instead.
+ */
+ @Deprecated
public static class BDDStubberImpl implements BDDStubber {
private final Stubber mockitoStubber;
@@ -283,7 +365,7 @@
return new BDDStubberImpl(mockitoStubber.doCallRealMethod());
}
}
-
+
/**
* see original {@link Mockito#doThrow(Throwable)}
* @since 1.8.0
@@ -299,23 +381,23 @@
public static BDDStubber willThrow(Class<? extends Throwable> toBeThrown) {
return new BDDStubberImpl(Mockito.doThrow(toBeThrown));
}
-
+
/**
* see original {@link Mockito#doAnswer(Answer)}
* @since 1.8.0
*/
public static BDDStubber willAnswer(Answer answer) {
return new BDDStubberImpl(Mockito.doAnswer(answer));
- }
-
+ }
+
/**
* see original {@link Mockito#doNothing()}
* @since 1.8.0
*/
public static BDDStubber willDoNothing() {
return new BDDStubberImpl(Mockito.doNothing());
- }
-
+ }
+
/**
* see original {@link Mockito#doReturn(Object)}
* @since 1.8.0
diff --git a/src/org/mockito/Incubating.java b/src/org/mockito/Incubating.java
index 9748fd3..ea53bd0 100644
--- a/src/org/mockito/Incubating.java
+++ b/src/org/mockito/Incubating.java
@@ -13,10 +13,10 @@
* The annotation conveys following information:
* <ul>
* <li>The API is fairly new and we would appreciate your feedback. For example, what are you missing from the API
- * to solve your use case (yes, please, real use cases).</li>
- * <li>For types or methods that are already released this annotation means that that the API might change.
- * The chance for that is small and we will always try to make any changes in a backwards compatible way.
- * The only reason we would want to change it is to provide better support for using and extending Mockito.
+ * to solve your use case.</li>
+ * <li>The API might change.
+ * The chance for that is small because we care great deal for the initial design.
+ * The incubating API might change based on the feedback from the community in order to make the API most useful for the users.
* </li>
* <li>
* For types or methods that are not yet released it means the API is <strong>work in progress</strong>
diff --git a/src/org/mockito/InjectMocks.java b/src/org/mockito/InjectMocks.java
index 48341a9..f1dbc7e 100644
--- a/src/org/mockito/InjectMocks.java
+++ b/src/org/mockito/InjectMocks.java
@@ -25,19 +25,23 @@
* i.e. you will have to provide dependencies yourself.
* <ol>
* <li><strong>Constructor injection</strong>; the biggest constructor is chosen,
- * then arguments are resolved with mocks declared in the test only.
+ * then arguments are resolved with mocks declared in the test only. If the object is successfully created
+ * with the constructor, then <strong>Mockito won't try the other strategies</strong>. Mockito has decided to no
+ * corrupt an object if it has a parametered constructor.
* <p><u>Note:</u> If arguments can not be found, then null is passed.
* If non-mockable types are wanted, then constructor injection won't happen.
* In these cases, you will have to satisfy dependencies yourself.</p></li>
*
- * <li><strong>Property setter injection</strong>; mocks will first be resolved by type,
+ * <li><strong>Property setter injection</strong>; mocks will first be resolved by type (if a single type match
+ * injection will happen regardless of the name),
* then, if there is several property of the same type, by the match of the property name and the mock name.
* <p><u>Note 1:</u> If you have properties with the same type (or same erasure), it's better to name all @Mock
* annotated fields with the matching properties, otherwise Mockito might get confused and injection won't happen.</p>
* <p><u>Note 2:</u> If @InjectMocks instance wasn't initialized before and have a no-arg constructor,
* then it will be initialized with this constructor.</p></li>
*
- * <li><strong>Field injection</strong>; mocks will first be resolved by type,
+ * <li><strong>Field injection</strong>; mocks will first be resolved by type (if a single type match
+ * injection will happen regardless of the name),
* then, if there is several property of the same type, by the match of the field name and the mock name.
* <p><u>Note 1:</u> If you have fields with the same type (or same erasure), it's better to name all @Mock
* annotated fields with the matching fields, otherwise Mockito might get confused and injection won't happen.</p>
@@ -73,7 +77,7 @@
* </p>
*
* <p>
- * In the above example the field ArticleManager annotated with @InjectMocks can have
+ * In the above example the field <code>ArticleManager</code> annotated with <code>@InjectMocks</code> can have
* a parameterized constructor only or a no-arg constructor only, or both.
* All these constructors can be package protected, protected or private, however
* <u>Mockito cannot instantiate inner classes, local classes, abstract classes and of course interfaces.</u>
@@ -142,6 +146,11 @@
* {@link org.mockito.runners.MockitoJUnitRunner}.
* </p>
*
+ * <p>
+ * Mockito is not an dependency injection framework, don't expect this shorthand utility to inject a complex graph of objects
+ * be it mocks/spies or real objects.
+ * </p>
+ *
* @see Mock
* @see Spy
* @see MockitoAnnotations#initMocks(Object)
diff --git a/src/org/mockito/Matchers.java b/src/org/mockito/Matchers.java
index 9e227cd..971452e 100644
--- a/src/org/mockito/Matchers.java
+++ b/src/org/mockito/Matchers.java
@@ -53,7 +53,7 @@
* <p>
* <b>Warning 2:</b>
* <p>
- * The any family methods <b>*don't do any type checks*</b>, those are only here to avoid casting
+ * The any family methods <b>*doesn't do any type checks*</b>, those are only here to avoid casting
* in your code. If you want to perform type checks use the {@link #isA(Class)} method.
* This <b>might</b> however change (type checks could be added) in a future major release.
*
@@ -104,12 +104,12 @@
@SuppressWarnings("unchecked")
public class Matchers {
- private static MockingProgress mockingProgress = new ThreadSafeMockingProgress();
+ private static final MockingProgress MOCKING_PROGRESS = new ThreadSafeMockingProgress();
/**
* Any <code>boolean</code>, <code>Boolean</code> or <code>null</code>.
* <p>
- * This method <b>*don't do any type checks*</b>, it is only there to avoid casting
+ * This method <b>*doesn'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.
* <p>
@@ -124,7 +124,7 @@
/**
* Any <code>byte</code>, <code>Byte</code> or <code>null</code>.
* <p>
- * This method <b>*don't do any type checks*</b>, it is only there to avoid casting
+ * This method <b>*doesn'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.
* <p>
@@ -139,7 +139,7 @@
/**
* Any <code>char</code>, <code>Character</code> or <code>null</code>.
* <p>
- * This method <b>*don't do any type checks*</b>, it is only there to avoid casting
+ * This method <b>*doesn'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.
* <p>
@@ -154,7 +154,7 @@
/**
* Any int, Integer or <code>null</code>.
* <p>
- * This method <b>*don't do any type checks*</b>, it is only there to avoid casting
+ * This method <b>*doesn'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.
* <p>
@@ -169,7 +169,7 @@
/**
* Any <code>long</code>, <code>Long</code> or <code>null</code>.
* <p>
- * This method <b>*don't do any type checks*</b>, it is only there to avoid casting
+ * This method <b>*doesn'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.
* <p>
@@ -184,7 +184,7 @@
/**
* Any <code>float</code>, <code>Float</code> or <code>null</code>.
* <p>
- * This method <b>*don't do any type checks*</b>, it is only there to avoid casting
+ * This method <b>*doesn'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.
* <p>
@@ -199,7 +199,7 @@
/**
* Any <code>double</code>, <code>Double</code> or <code>null</code>.
* <p>
- * This method <b>*don't do any type checks*</b>, it is only there to avoid casting
+ * This method <b>*doesn'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.
* <p>
@@ -214,7 +214,7 @@
/**
* Any <code>short</code>, <code>Short</code> or <code>null</code>.
* <p>
- * This method <b>*don't do any type checks*</b>, it is only there to avoid casting
+ * This method <b>*doesn'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.
* <p>
@@ -229,7 +229,7 @@
/**
* Any <code>Object</code> or <code>null</code>.
* <p>
- * This method <b>*don't do any type checks*</b>, it is only there to avoid casting
+ * This method <b>*doesn'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.
* <p>
@@ -278,7 +278,7 @@
* <p>
* Alias to {@link Matchers#anyObject()}
* <p>
- * This method <b>*don't do any type checks*</b>, it is only there to avoid casting
+ * This method <b>*doesn'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.
* <p>
@@ -296,7 +296,7 @@
* <p>
* Shorter alias to {@link Matchers#anyObject()}
* <p>
- * This method <b>*don't do any type checks*</b>, it is only there to avoid casting
+ * This method <b>*doesn'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.
* <p>
@@ -311,7 +311,7 @@
/**
* Any <code>String</code> or <code>null</code>.
* <p>
- * This method <b>*don't do any type checks*</b>, it is only there to avoid casting
+ * This method <b>*doesn'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.
* <p>
@@ -326,7 +326,7 @@
/**
* Any <code>List</code> or <code>null</code>.
* <p>
- * This method <b>*don't do any type checks*</b>, it is only there to avoid casting
+ * This method <b>*doesn'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.
* <p>
@@ -344,7 +344,7 @@
* <p>
* Any <code>List</code> or <code>null</code>.
* <p>
- * This method <b>*don't do any type checks*</b>, it is only there to avoid casting
+ * This method <b>*doesn'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.
* <p>
@@ -360,7 +360,7 @@
/**
* Any <code>Set</code> or <code>null</code>.
* <p>
- * This method <b>*don't do any type checks*</b>, it is only there to avoid casting
+ * This method <b>*doesn'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.
* <p>
@@ -378,7 +378,7 @@
* <p>
* Any <code>Set</code> or <code>null</code>
* <p>
- * This method <b>*don't do any type checks*</b>, it is only there to avoid casting
+ * This method <b>*dones'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.
* <p>
@@ -394,7 +394,7 @@
/**
* Any <code>Map</code> or <code>null</code>.
* <p>
- * This method <b>*don't do any type checks*</b>, it is only there to avoid casting
+ * This method <b>*doesn'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.
* <p>
@@ -412,7 +412,7 @@
* <p>
* Any <code>Map</code> or <code>null</code>
* <p>
- * This method <b>*don't do any type checks*</b>, it is only there to avoid casting
+ * This method <b>*doesn'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.
* <p>
@@ -429,7 +429,7 @@
/**
* Any <code>Collection</code> or <code>null</code>.
* <p>
- * This method <b>*don't do any type checks*</b>, it is only there to avoid casting
+ * This method <b>*dones'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.
* <p>
@@ -447,7 +447,7 @@
* <p>
* Any <code>Collection</code> or <code>null</code>.
* <p>
- * This method <b>*don't do any type checks*</b>, it is only there to avoid casting
+ * This method <b>*doesn'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.
* <p>
@@ -875,6 +875,6 @@
}
private static HandyReturnValues reportMatcher(Matcher<?> matcher) {
- return mockingProgress.getArgumentMatcherStorage().reportMatcher(matcher);
+ return MOCKING_PROGRESS.getArgumentMatcherStorage().reportMatcher(matcher);
}
}
diff --git a/src/org/mockito/MockSettings.java b/src/org/mockito/MockSettings.java
index 7f84b1c..2b5f934 100644
--- a/src/org/mockito/MockSettings.java
+++ b/src/org/mockito/MockSettings.java
@@ -5,7 +5,7 @@
package org.mockito;
import org.mockito.listeners.InvocationListener;
-import org.mockito.mock.MockCreationSettings;
+import org.mockito.mock.SerializableMode;
import org.mockito.stubbing.Answer;
import java.io.Serializable;
@@ -162,6 +162,25 @@
MockSettings serializable();
/**
+ * Configures the mock to be serializable with a specific serializable mode.
+ * With this feature you can use a mock in a place that requires dependencies to be serializable.
+ * <p>
+ * WARNING: This should be rarely used in unit testing.
+ * <p>
+ * The behaviour was implemented for a specific use case of a BDD spec that had an unreliable external dependency. This
+ * was in a web environment and the objects from the external dependency were being serialized to pass between layers.
+ *
+ * <pre class="code"><code class="java">
+ * List serializableMock = mock(List.class, withSettings().serializable(SerializableMode.ACROSS_CLASSLOADERS));
+ * </code></pre>
+ *
+ * @param mode serialization mode
+ * @return settings instance so that you can fluently specify other settings
+ * @since 1.10.0
+ */
+ MockSettings serializable(SerializableMode mode);
+
+ /**
* Enables real-time logging of method invocations on this mock. Can be used
* during test debugging in order to find wrong interactions with this mock.
* <p>
@@ -199,7 +218,6 @@
MockSettings invocationListeners(InvocationListener... listeners);
/**
- * Sets whether this mock should only provide stubbing of methods.
* A stub-only mock does not record method
* invocations, thus saving memory but
* disallowing verification of invocations.
@@ -211,4 +229,41 @@
*
* @return settings instance so that you can fluently specify other settings
*/
- MockSettings stubOnly();}
+ MockSettings stubOnly();
+
+ /**
+ * Mockito attempts to use constructor when creating instance of the mock.
+ * This is particularly useful for spying on abstract classes. See also {@link Mockito#spy(Class)}.
+ * <p>
+ * Example:
+ * <pre class="code"><code class="java">
+ * //Robust API, via settings builder:
+ * OtherAbstract spy = mock(OtherAbstract.class, withSettings()
+ * .useConstructor().defaultAnswer(CALLS_REAL_METHODS));
+ *
+ * //Mocking a non-static inner abstract class:
+ * InnerAbstract spy = mock(InnerAbstract.class, withSettings()
+ * .useConstructor().outerInstance(outerInstance).defaultAnswer(CALLS_REAL_METHODS));
+ * </code></pre>
+ *
+ * @return settings instance so that you can fluently specify other settings
+ * @since 1.10.12
+ */
+ @Incubating
+ MockSettings useConstructor();
+
+ /**
+ * Makes it possible to mock non-static inner classes in conjunction with {@link #useConstructor()}.
+ * <p>
+ * Example:
+ * <pre class="code"><code class="java">
+ * InnerClass mock = mock(InnerClass.class, withSettings()
+ * .useConstructor().outerInstance(outerInstance).defaultAnswer(CALLS_REAL_METHODS));
+ * </code></pre>
+ *
+ * @return settings instance so that you can fluently specify other settings
+ * @since 1.10.12
+ */
+ @Incubating
+ MockSettings outerInstance(Object outerClassInstance);
+}
diff --git a/src/org/mockito/MockingDetails.java b/src/org/mockito/MockingDetails.java
index b00e23a..46099b5 100644
--- a/src/org/mockito/MockingDetails.java
+++ b/src/org/mockito/MockingDetails.java
@@ -1,20 +1,23 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito;
+import org.mockito.invocation.Invocation;
+
+import java.util.Collection;
+
/**
* Provides mocking information.
* For example, you can identify whether a particular object is either a mock or a spy.
*
* @since 1.9.5
*/
-@Incubating
public interface MockingDetails {
/**
- * Informs if the object is a mock.
+ * Informs if the object is a mock. isMock() for null input returns false.
* @return true if the object is a mock or a spy.
*
* @since 1.9.5
@@ -22,10 +25,19 @@
boolean isMock();
/**
- * Informs if the object is a spy.
+ * Informs if the object is a spy. isSpy() for null input returns false.
* @return true if the object is a spy.
*
* @since 1.9.5
*/
boolean isSpy();
+
+ /**
+ * Provides a collection of methods indicating the invocations of the object
+ * @return collection of Invocation representing the invocations
+ * for the object.
+ *
+ * @since 1.10.0
+ */
+ Collection<Invocation> getInvocations();
}
\ No newline at end of file
diff --git a/src/org/mockito/Mockito.java b/src/org/mockito/Mockito.java
index a39917f..4c03cc0 100644
--- a/src/org/mockito/Mockito.java
+++ b/src/org/mockito/Mockito.java
@@ -13,31 +13,30 @@
import org.mockito.internal.verification.VerificationModeFactory;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.*;
-import org.mockito.verification.Timeout;
-import org.mockito.verification.VerificationMode;
-import org.mockito.verification.VerificationWithTimeout;
+import org.mockito.verification.*;
+import org.mockito.junit.*;
/**
* <p align="left"><img src="logo.jpg"/></p>
* Mockito library enables mocks creation, verification and stubbing.
* <p>
- * This javadoc content is also available on the <a href="http://mockito.org">http://mockito.org</a> web page.
+ * This javadoc content is also available on the <a href="http://mockito.org">http://mockito.org</a> web page.
* All documentation is kept in javadocs because it guarantees consistency between what's on the web and what's in the source code.
- * Also, it makes possible to access documentation straight from the IDE even if you work offline.
- *
+ * Also, it makes possible to access documentation straight from the IDE even if you work offline.
+ *
* <h1>Contents</h1>
- *
- * <b>
- * <a href="#1">1. Let's verify some behaviour! </a><br/>
+ *
+ * <b>
+ * <a href="#1">1. Let's verify some behaviour! </a><br/>
* <a href="#2">2. How about some stubbing? </a><br/>
* <a href="#3">3. Argument matchers </a><br/>
- * <a href="#4">4. Verifying exact number of invocations / at least once / never </a><br/>
- * <a href="#5">5. Stubbing void methods with exceptions </a><br/>
- * <a href="#6">6. Verification in order </a><br/>
- * <a href="#7">7. Making sure interaction(s) never happened on mock </a><br/>
- * <a href="#8">8. Finding redundant invocations </a><br/>
+ * <a href="#4">4. Verifying exact number of invocations / at least once / never </a><br/>
+ * <a href="#5">5. Stubbing void methods with exceptions </a><br/>
+ * <a href="#6">6. Verification in order </a><br/>
+ * <a href="#7">7. Making sure interaction(s) never happened on mock </a><br/>
+ * <a href="#8">8. Finding redundant invocations </a><br/>
* <a href="#9">9. Shorthand for mocks creation - <code>@Mock</code> annotation </a><br/>
- * <a href="#10">10. Stubbing consecutive calls (iterator-style stubbing) </a><br/>
+ * <a href="#10">10. Stubbing consecutive calls (iterator-style stubbing) </a><br/>
* <a href="#11">11. Stubbing with callbacks </a><br/>
* <a href="#12">12. <code>doReturn()</code>|<code>doThrow()</code>|<code>doAnswer()</code>|<code>doNothing()</code>|<code>doCallRealMethod()</code> family of methods</a><br/>
* <a href="#13">13. Spying on real objects </a><br/>
@@ -50,14 +49,16 @@
* <a href="#20">20. Serializable mocks (Since 1.8.1) </a><br/>
* <a href="#21">21. New annotations: <code>@Captor</code>, <code>@Spy</code>, <code>@InjectMocks</code> (Since 1.8.3) </a><br/>
* <a href="#22">22. Verification with timeout (Since 1.8.5) </a><br/>
- * <a href="#23">23. (New) Automatic instantiation of <code>@Spies</code>, <code>@InjectMocks</code> and constructor injection goodness (Since 1.9.0)</a><br/>
- * <a href="#24">24. (New) One-liner stubs (Since 1.9.0)</a><br/>
- * <a href="#25">25. (New) Verification ignoring stubs (Since 1.9.0)</a><br/>
- * <a href="#26">26. (**New**) Mocking details (Since 1.9.5)</a><br/>
- * <a href="#27">27. (**New**) Delegate calls to real instance (Since 1.9.5)</a><br/>
- * <a href="#28">28. (**New**) <code>MockMaker</code> API (Since 1.9.5)</a><br/>
+ * <a href="#23">23. Automatic instantiation of <code>@Spies</code>, <code>@InjectMocks</code> and constructor injection goodness (Since 1.9.0)</a><br/>
+ * <a href="#24">24. One-liner stubs (Since 1.9.0)</a><br/>
+ * <a href="#25">25. Verification ignoring stubs (Since 1.9.0)</a><br/>
+ * <a href="#26">26. Mocking details (Since 1.9.5)</a><br/>
+ * <a href="#27">27. Delegate calls to real instance (Since 1.9.5)</a><br/>
+ * <a href="#28">28. <code>MockMaker</code> API (Since 1.9.5)</a><br/>
+ * <a href="#29">29. (new) BDD style verification (Since 1.10.0)</a><br/>
+ * <a href="#30">30. (new) Spying or mocking abstract classes (Since 1.10.12)</a><br/>
* </b>
- *
+ *
* <p>
* Following examples mock a List, because everyone knows its interface (methods
* like <code>add()</code>, <code>get()</code>, <code>clear()</code> will be used). <br>
@@ -67,11 +68,11 @@
*
*
* <h3 id="1">1. <a class="meaningful_link" href="#verification">Let's verify some behaviour!</a></h3>
- *
+ *
* <pre class="code"><code class="java">
* //Let's import Mockito statically so that the code looks clearer
* import static org.mockito.Mockito.*;
- *
+ *
* //mock creation
* List mockedList = mock(List.class);
*
@@ -83,7 +84,7 @@
* verify(mockedList).add("one");
* verify(mockedList).clear();
* </code></pre>
- *
+ *
* <p>
* Once created, mock will remember all interactions. Then you can selectively
* verify whatever interaction you are interested in.
@@ -92,47 +93,47 @@
*
*
* <h3 id="2">2. <a class="meaningful_link" href="#stubbing">How about some stubbing?</a></h3>
- *
+ *
* <pre class="code"><code class="java">
* //You can mock concrete classes, not only interfaces
* LinkedList mockedList = mock(LinkedList.class);
- *
+ *
* //stubbing
* when(mockedList.get(0)).thenReturn("first");
* when(mockedList.get(1)).thenThrow(new RuntimeException());
- *
+ *
* //following prints "first"
* System.out.println(mockedList.get(0));
- *
+ *
* //following throws runtime exception
* System.out.println(mockedList.get(1));
- *
+ *
* //following prints "null" because get(999) was not stubbed
* System.out.println(mockedList.get(999));
- *
+ *
* //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 before even verify() gets executed).
* //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>
- *
+ *
* <ul>
* <li> By default, for all methods that return value, mock returns null, an
* empty collection or appropriate primitive/primitive wrapper value (e.g: 0,
* false, ... for int/Integer, boolean/Boolean, ...). </li>
- *
+ *
* <li> Stubbing can be overridden: for example common stubbing can go to
* fixture setup but the test methods can override it.
* Please note that overridding stubbing is a potential code smell that points out too much stubbing</li>
- *
+ *
* <li> Once stubbed, the method will always return stubbed value regardless
* of how many times it is called. </li>
- *
+ *
* <li> Last stubbing is more important - when you stubbed the same method with
* the same arguments many times.
* Other words: <b>the order of stubbing matters</b> but it is only meaningful rarely,
* e.g. when stubbing exactly the same method calls or sometimes when argument matchers are used, etc.</li>
- *
+ *
* </ul>
*
*
@@ -140,25 +141,25 @@
* <h3 id="3">3. <a class="meaningful_link" href="#argument_matchers">Argument matchers</a></h3>
*
* Mockito verifies argument values in natural java style: by using an <code>equals()</code> method.
- * Sometimes, when extra flexibility is required then you might use argument matchers:
- *
+ * Sometimes, when extra flexibility is required then you might use argument matchers:
+ *
* <pre class="code"><code class="java">
* //stubbing using built-in anyInt() argument matcher
* when(mockedList.get(anyInt())).thenReturn("element");
- *
+ *
* //stubbing using hamcrest (let's say isValid() returns your own hamcrest matcher):
* when(mockedList.contains(argThat(isValid()))).thenReturn("element");
- *
+ *
* //following prints "element"
* System.out.println(mockedList.get(999));
- *
+ *
* //<b>you can also verify using an argument matcher</b>
* verify(mockedList).get(anyInt());
* </code></pre>
- *
+ *
* <p>
- * Argument matchers allow flexible verification or stubbing.
- * {@link Matchers Click here to see} more built-in matchers
+ * Argument matchers allow flexible verification or stubbing.
+ * {@link Matchers Click here to see} more built-in matchers
* and examples of <b>custom argument matchers / hamcrest matchers</b>.
* <p>
* For information solely on <b>custom argument matchers</b> check out javadoc for {@link ArgumentMatcher} class.
@@ -168,7 +169,7 @@
* Sometimes it's just better to refactor the code to allow <code>equals()</code> matching or even implement <code>equals()</code> method to help out with testing.
* <p>
* Also, read <a href="#15">section 15</a> or javadoc for {@link ArgumentCaptor} class.
- * {@link ArgumentCaptor} is a special implementation of an argument matcher that captures argument values for further assertions.
+ * {@link ArgumentCaptor} is a special implementation of an argument matcher that captures argument values for further assertions.
* <p>
* <b>Warning on argument matchers:</b>
* <p>
@@ -176,15 +177,15 @@
* by matchers.
* <p>
* E.g: (example shows verification but the same applies to stubbing):
- *
+ *
* <pre class="code"><code class="java">
* verify(mock).someMethod(anyInt(), anyString(), <b>eq("third argument")</b>);
* //above is correct - eq() is also an argument matcher
- *
+ *
* verify(mock).someMethod(anyInt(), anyString(), <b>"third argument"</b>);
* //above is incorrect - exception will be thrown because third argument is given without an argument matcher.
* </code></pre>
- *
+ *
* <p>
* Matcher methods like <code>anyObject()</code>, <code>eq()</code> <b>do not</b> return matchers.
* Internally, they record a matcher on a stack and return a dummy value (usually null).
@@ -198,34 +199,34 @@
* <a class="meaningful_link" href="#at_least_verification">at least x</a> / never</h3>
*
* <pre class="code"><code class="java">
- * //using mock
+ * //using mock
* mockedList.add("once");
- *
+ *
* mockedList.add("twice");
* mockedList.add("twice");
- *
+ *
* mockedList.add("three times");
* mockedList.add("three times");
* mockedList.add("three times");
- *
+ *
* //following two verifications work exactly the same - times(1) is used by default
* verify(mockedList).add("once");
* verify(mockedList, times(1)).add("once");
- *
+ *
* //exact number of invocations verification
* verify(mockedList, times(2)).add("twice");
* verify(mockedList, times(3)).add("three times");
- *
+ *
* //verification using never(). never() is an alias to times(0)
* verify(mockedList, never()).add("never happened");
- *
+ *
* //verification using atLeast()/atMost()
* verify(mockedList, atLeastOnce()).add("three times");
* verify(mockedList, atLeast(2)).add("five times");
* verify(mockedList, atMost(5)).add("three times");
- *
+ *
* </code></pre>
- *
+ *
* <p>
* <b>times(1) is the default.</b> Therefore using times(1) explicitly can be
* omitted.
@@ -234,25 +235,25 @@
*
*
* <h3 id="5">5. <a class="meaningful_link" href="#stubbing_with_exceptions">Stubbing void methods with exceptions</a></h3>
- *
+ *
* <pre class="code"><code class="java">
* doThrow(new RuntimeException()).when(mockedList).clear();
- *
+ *
* //following throws RuntimeException:
* mockedList.clear();
* </code></pre>
- *
+ *
* Read more about doThrow|doAnswer family of methods in paragraph 12.
* <p>
* Initially, {@link Mockito#stubVoid(Object)} was used for stubbing voids.
* Currently <code>stubVoid()</code> is deprecated in favor of {@link Mockito#doThrow(Throwable)}.
- * This is because of improved readability and consistency with the family of {@link Mockito#doAnswer(Answer)} methods.
+ * This is because of improved readability and consistency with the family of {@link Mockito#doAnswer(Answer)} methods.
*
*
*
*
* <h3 id="6">6. <a class="meaningful_link" href="#in_order_verification">Verification in order</a></h3>
- *
+ *
* <pre class="code"><code class="java">
* // A. Single mock whose methods must be invoked in a particular order
* List singleMock = mock(List.class);
@@ -271,21 +272,21 @@
* // B. Multiple mocks that must be used in a particular order
* List firstMock = mock(List.class);
* List secondMock = mock(List.class);
- *
+ *
* //using mocks
* firstMock.add("was called first");
* secondMock.add("was called second");
- *
+ *
* //create inOrder object passing any mocks that need to be verified in order
* InOrder inOrder = inOrder(firstMock, secondMock);
- *
+ *
* //following will make sure that firstMock was called before secondMock
* inOrder.verify(firstMock).add("was called first");
* inOrder.verify(secondMock).add("was called second");
*
* // Oh, and A + B can be mixed together at will
* </code></pre>
- *
+ *
* Verification in order is flexible - <b>you don't have to verify all
* interactions</b> one-by-one but only those that you are interested in
* testing in order.
@@ -297,20 +298,20 @@
*
*
* <h3 id="7">7. <a class="meaningful_link" href="#never_verification">Making sure interaction(s) never happened on mock</a></h3>
- *
+ *
* <pre class="code"><code class="java">
* //using mocks - only mockOne is interacted
* mockOne.add("one");
- *
+ *
* //ordinary verification
* verify(mockOne).add("one");
- *
+ *
* //verify that method was never called on a mock
* verify(mockOne, never()).add("two");
- *
+ *
* //verify that other mocks were not interacted
* verifyZeroInteractions(mockTwo, mockThree);
- *
+ *
* </code></pre>
*
*
@@ -322,21 +323,21 @@
* //using mocks
* mockedList.add("one");
* mockedList.add("two");
- *
+ *
* verify(mockedList).add("one");
- *
- * //following verification will fail
+ *
+ * //following verification will fail
* verifyNoMoreInteractions(mockedList);
* </code></pre>
- *
- * A word of <b>warning</b>:
+ *
+ * A word of <b>warning</b>:
* 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. You can find further reading
* <a href="http://monkeyisland.pl/2008/07/12/should-i-worry-about-the-unexpected/">here</a>.
- *
- * <p>
+ *
+ * <p>
* See also {@link Mockito#never()} - it is more explicit and
* communicates the intent well.
* <p>
@@ -352,25 +353,25 @@
* <li>Makes the verification error easier to read because the <b>field name</b>
* is used to identify the mock.</li>
* </ul>
- *
+ *
* <pre class="code"><code class="java">
- * public class ArticleManagerTest {
- *
+ * public class ArticleManagerTest {
+ *
* @Mock private ArticleCalculator calculator;
* @Mock private ArticleDatabase database;
* @Mock private UserProvider userProvider;
- *
+ *
* private ArticleManager manager;
* </code></pre>
- *
+ *
* <b>Important!</b> This needs to be somewhere in the base class or a test
* runner:
- *
+ *
* <pre class="code"><code class="java">
* MockitoAnnotations.initMocks(testClass);
* </code></pre>
- *
- * You can use built-in runner: {@link MockitoJUnitRunner}.
+ *
+ * You can use built-in runner: {@link MockitoJUnitRunner} or a rule: {@link MockitoRule}.
* <p>
* Read more here: {@link MockitoAnnotations}
*
@@ -378,33 +379,33 @@
*
*
* <h3 id="10">10. <a class="meaningful_link" href="#stubbing_consecutive_calls">Stubbing consecutive calls</a> (iterator-style stubbing)</h3>
- *
+ *
* Sometimes we need to stub with different return value/exception for the same
- * method call. Typical use case could be mocking iterators.
- * Original version of Mockito did not have this feature to promote simple mocking.
+ * method call. Typical use case could be mocking iterators.
+ * Original version of Mockito did not have this feature to promote simple mocking.
* For example, instead of iterators one could use {@link Iterable} or simply
* collections. Those offer natural ways of stubbing (e.g. using real
* collections). In rare scenarios stubbing consecutive calls could be useful,
* though:
* <p>
- *
+ *
* <pre class="code"><code class="java">
* when(mock.someMethod("some arg"))
* .thenThrow(new RuntimeException())
* .thenReturn("foo");
- *
+ *
* //First call: throws runtime exception:
* mock.someMethod("some arg");
- *
+ *
* //Second call: prints "foo"
* System.out.println(mock.someMethod("some arg"));
- *
- * //Any consecutive call: prints "foo" as well (last stubbing wins).
+ *
+ * //Any consecutive call: prints "foo" as well (last stubbing wins).
* System.out.println(mock.someMethod("some arg"));
* </code></pre>
- *
+ *
* Alternative, shorter version of consecutive stubbing:
- *
+ *
* <pre class="code"><code class="java">
* when(mock.someMethod("some arg"))
* .thenReturn("one", "two", "three");
@@ -421,7 +422,7 @@
* originally. We recommend using simple stubbing with <code>thenReturn()</code> or
* <code>thenThrow()</code> only. Those two should be <b>just enough</b> to test/test-drive
* any clean & simple code.
- *
+ *
* <pre class="code"><code class="java">
* when(mock.someMethod(anyString())).thenAnswer(new Answer() {
* Object answer(InvocationOnMock invocation) {
@@ -430,7 +431,7 @@
* return "called with arguments: " + args;
* }
* });
- *
+ *
* //Following prints "called with arguments: foo"
* System.out.println(mock.someMethod("foo"));
* </code></pre>
@@ -444,13 +445,13 @@
* Stubbing voids requires different approach from {@link Mockito#when(Object)} because the compiler does not
* like void methods inside brackets...
* <p>
- * {@link Mockito#doThrow(Throwable)} replaces the {@link Mockito#stubVoid(Object)} method for stubbing voids.
+ * {@link Mockito#doThrow(Throwable)} replaces the {@link Mockito#stubVoid(Object)} method for stubbing voids.
* The main reason is improved readability and consistency with the family of <code>doAnswer()</code> methods.
* <p>
* Use <code>doThrow()</code> when you want to stub a void method with an exception:
* <pre class="code"><code class="java">
* doThrow(new RuntimeException()).when(mockedList).clear();
- *
+ *
* //following throws RuntimeException:
* mockedList.clear();
* </code></pre>
@@ -484,17 +485,17 @@
*
*
* <h3 id="13">13. <a class="meaningful_link" href="#spy">Spying on real objects</a></h3>
- *
+ *
* You can create spies of real objects. When you use the spy then the <b>real</b> methods are called
* (unless a method was stubbed).
* <p>
* Real spies should be used <b>carefully and occasionally</b>, for example when dealing with legacy code.
- *
+ *
* <p>
- * Spying on real objects can be associated with "partial mocking" concept.
- * <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
+ * Spying on real objects can be associated with "partial mocking" concept.
+ * <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, the full article is <a href=
* "http://monkeyisland.pl/2009/01/13/subclass-and-override-vs-partial-mocking-vs-refactoring"
* >here</a>)
@@ -503,25 +504,25 @@
* <pre class="code"><code class="java">
* List list = new LinkedList();
* List spy = spy(list);
- *
+ *
* //optionally, you can stub out some methods:
* when(spy.size()).thenReturn(100);
- *
+ *
* //using the spy calls <b>*real*</b> methods
* spy.add("one");
* spy.add("two");
- *
+ *
* //prints "one" - the first element of a list
* System.out.println(spy.get(0));
- *
+ *
* //size() method was stubbed - 100 is printed
* System.out.println(spy.size());
- *
+ *
* //optionally, you can verify
* verify(spy).add("one");
* verify(spy).add("two");
* </code></pre>
- *
+ *
* <h4>Important gotcha on spying real objects!</h4>
* <ol>
* <li>Sometimes it's impossible or impractical to use {@link Mockito#when(Object)} for stubbing spies.
@@ -563,12 +564,12 @@
* However, it can be helpful for working with <b>legacy systems</b>.
* <p>
* It is the default answer so it will be used <b>only when you don't</b> stub the method call.
- *
+ *
* <pre class="code"><code class="java">
* Foo mock = mock(Foo.class, Mockito.RETURNS_SMART_NULLS);
- * Foo mockTwo = mock(Foo.class, new YourOwnAnswer());
+ * Foo mockTwo = mock(Foo.class, new YourOwnAnswer());
* </code></pre>
- *
+ *
* <p>
* Read more about this interesting implementation of <i>Answer</i>: {@link Mockito#RETURNS_SMART_NULLS}
*
@@ -576,7 +577,7 @@
*
*
* <h3 id="15">15. <a class="meaningful_link" href="#captors">Capturing arguments</a> for further assertions (Since 1.8.0)</h3>
- *
+ *
* Mockito verifies argument values in natural java style: by using an <code>equals()</code> method.
* This is also the recommended way of matching arguments because it makes tests clean & simple.
* In some situations though, it is helpful to assert on certain arguments after the actual verification.
@@ -586,15 +587,15 @@
* verify(mock).doSomething(argument.capture());
* assertEquals("John", argument.getValue().getName());
* </code></pre>
- *
+ *
* <b>Warning:</b> it is recommended to use ArgumentCaptor with verification <b>but not</b> with stubbing.
* Using ArgumentCaptor with stubbing may decrease test readability because captor is created outside of assert (aka verify or 'then') block.
* Also it may reduce defect localization because if stubbed method was not called then no argument is captured.
* <p>
* In a way ArgumentCaptor is related to custom argument matchers (see javadoc for {@link ArgumentMatcher} class).
- * Both techniques can be used for making sure certain arguments where passed to mocks.
+ * Both techniques can be used for making sure certain arguments where passed to mocks.
* However, ArgumentCaptor may be a better fit if:
- * <ul>
+ * <ul>
* <li>custom argument matcher is not likely to be reused</li>
* <li>you just need it to assert on argument values to complete verification</li>
* </ul>
@@ -604,32 +605,32 @@
*
*
* <h3 id="16">16. <a class="meaningful_link" href="#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 - 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.
+ * Read more about spying: <a href="#13">here</a> or in javadoc for {@link Mockito#spy(Object)} method.
* <p>
* <pre class="code"><code class="java">
- * //you can create partial mock with spy() method:
+ * //you can create partial mock with spy() method:
* List list = spy(new LinkedList());
- *
+ *
* //you can enable partial mock capabilities selectively on mocks:
* Foo mock = mock(Foo.class);
* //Be sure the real implementation is 'safe'.
* //If real implementation throws exceptions or depends on specific state of the object then you're in trouble.
* when(mock.someMethod()).thenCallRealMethod();
* </code></pre>
- *
+ *
* As usual you are going to read <b>the partial mock warning</b>:
* Object oriented programming is more less tackling complexity by dividing the complexity into separate, specific, SRPy objects.
- * How does partial mock fit into this paradigm? Well, it just doesn't...
+ * How does partial mock fit into this paradigm? Well, it just doesn't...
* Partial mock usually means that the complexity has been moved to a different method on the same object.
* In most cases, this is not the way you want to design your application.
* <p>
- * However, there are rare cases when partial mocks come handy:
+ * However, there are rare cases when partial mocks come handy:
* dealing with code you cannot change easily (3rd party interfaces, interim refactoring of legacy code etc.)
* However, I wouldn't use partial mocks for new, test-driven & well-designed code.
*
@@ -637,13 +638,13 @@
*
*
* <h3 id="17">17. <a class="meaningful_link" href="#resetting_mocks">Resetting mocks</a> (Since 1.8.0)</h3>
- *
+ *
* Smart Mockito users hardly use this feature because they know it could be a sign of poor tests.
- * Normally, you don't need to reset your mocks, just create new mocks for each test method.
+ * Normally, you don't need to reset your mocks, just create new mocks for each test method.
* <p>
* Instead of <code>reset()</code> please consider writing simple, small and focused test methods over lengthy, over-specified tests.
* <b>First potential code smell is <code>reset()</code> in the middle of the test method.</b> This probably means you're testing too much.
- * Follow the whisper of your test methods: "Please keep us small & focused on single behavior".
+ * Follow the whisper of your test methods: "Please keep us small & focused on single behavior".
* There are several threads about it on mockito mailing list.
* <p>
* The only reason we added <code>reset()</code> method is to
@@ -656,7 +657,7 @@
* List mock = mock(List.class);
* when(mock.size()).thenReturn(10);
* mock.add(1);
- *
+ *
* reset(mock);
* //at this point the mock forgot any interactions & stubbing
* </code></pre>
@@ -666,47 +667,47 @@
*
* <h3 id="18">18. <a class="meaningful_link" href="#framework_validation">Troubleshooting & validating framework usage</a> (Since 1.8.0)</h3>
*
- * First of all, in case of any trouble, I encourage you to read the Mockito FAQ:
+ * First of all, in case of any trouble, I encourage you to read the Mockito FAQ:
* <a href="http://code.google.com/p/mockito/wiki/FAQ">http://code.google.com/p/mockito/wiki/FAQ</a>
* <p>
- * In case of questions you may also post to mockito mailing list:
+ * In case of questions you may also post to mockito mailing list:
* <a href="http://groups.google.com/group/mockito">http://groups.google.com/group/mockito</a>
* <p>
- * Next, you should know that Mockito validates if you use it correctly <b>all the time</b>.
+ * Next, you should know that Mockito validates if you use it correctly <b>all the time</b>.
* However, there's a gotcha so please read the javadoc for {@link Mockito#validateMockitoUsage()}
*
*
*
*
* <h3 id="19">19. <a class="meaningful_link" href="#bdd_mockito">Aliases for behavior driven development</a> (Since 1.8.0)</h3>
- *
+ *
* Behavior Driven Development style of writing tests uses <b>//given //when //then</b> comments as fundamental parts of your test methods.
* This is exactly how we write our tests and we warmly encourage you to do so!
* <p>
* Start learning about BDD here: <a href="http://en.wikipedia.org/wiki/Behavior_Driven_Development">http://en.wikipedia.org/wiki/Behavior_Driven_Development</a>
* <p>
* The problem is that current stubbing api with canonical role of <b>when</b> word does not integrate nicely with <b>//given //when //then</b> comments.
- * It's because stubbing belongs to <b>given</b> component of the test and not to the <b>when</b> component of the test.
- * Hence {@link BDDMockito} class introduces an alias so that you stub method calls with {@link BDDMockito#given(Object)} method.
- * Now it really nicely integrates with the <b>given</b> component of a BDD style test!
+ * It's because stubbing belongs to <b>given</b> component of the test and not to the <b>when</b> component of the test.
+ * Hence {@link BDDMockito} class introduces an alias so that you stub method calls with {@link BDDMockito#given(Object)} method.
+ * Now it really nicely integrates with the <b>given</b> component of a BDD style test!
* <p>
- * Here is how the test might look like:
+ * Here is how the test might look like:
* <pre class="code"><code class="java">
* import static org.mockito.BDDMockito.*;
- *
+ *
* Seller seller = mock(Seller.class);
* Shop shop = new Shop(seller);
- *
+ *
* public void shouldBuyBread() throws Exception {
- * //given
+ * //given
* given(seller.askForBread()).willReturn(new Bread());
- *
+ *
* //when
* Goods goods = shop.buyBread();
- *
+ *
* //then
* assertThat(goods, containBread());
- * }
+ * }
* </code></pre>
*
*
@@ -716,10 +717,10 @@
*
* Mocks can be made serializable. With this feature you can use a mock in a place that requires dependencies to be serializable.
* <p>
- * WARNING: This should be rarely used in unit testing.
+ * WARNING: This should be rarely used in unit testing.
* <p>
* The behaviour was implemented for a specific use case of a BDD spec that had an unreliable external dependency. This
- * was in a web environment and the objects from the external dependency were being serialized to pass between layers.
+ * was in a web environment and the objects from the external dependency were being serialized to pass between layers.
* <p>
* To create serializable mock use {@link MockSettings#serializable()}:
* <pre class="code"><code class="java">
@@ -729,9 +730,9 @@
* The mock can be serialized assuming all the normal <a href='http://java.sun.com/j2se/1.5.0/docs/api/java/io/Serializable.html'>
* serialization requirements</a> are met by the class.
* <p>
- * Making a real object spy serializable is a bit more effort as the spy(...) method does not have an overloaded version
+ * Making a real object spy serializable is a bit more effort as the spy(...) method does not have an overloaded version
* which accepts MockSettings. No worries, you will hardly ever use it.
- *
+ *
* <pre class="code"><code class="java">
* List<Object> list = new ArrayList<Object>();
* List<Object> spy = mock(ArrayList.class, withSettings()
@@ -749,21 +750,23 @@
*
* <p>
* Release 1.8.3 brings new annotations that may be helpful on occasion:
- *
+ *
* <ul>
- * <li>@{@link Captor} simplifies creation of {@link ArgumentCaptor}
+ * <li>@{@link Captor} simplifies creation of {@link ArgumentCaptor}
* - useful when the argument to capture is a nasty generic class and you want to avoid compiler warnings
- * <li>@{@link Spy} - you can use it instead {@link Mockito#spy(Object)}.
+ * <li>@{@link Spy} - you can use it instead {@link Mockito#spy(Object)}.
* <li>@{@link InjectMocks} - injects mock or spy fields into tested object automatically.
* </ul>
*
* <p>
- * Note that @{@link InjectMocks} can only be used in combination with the @{@link Spy} annotation, it means
- * that Mockito will inject mocks in a partial mock under testing. As a remainder, please read point 16 about partial mocks.
+ * Note that @{@link InjectMocks} can also be used in combination with the @{@link Spy} annotation, it means
+ * that Mockito will inject mocks into the partial mock under test. This complexity is another good reason why you
+ * should only use partial mocks as a last resort. See point 16 about partial mocks.
*
* <p>
* All new annotations are <b>*only*</b> processed on {@link MockitoAnnotations#initMocks(Object)}.
- * Just like for @{@link Mock} annotation you can use the built-in runner: {@link MockitoJUnitRunner}.
+ * Just like for @{@link Mock} annotation you can use the built-in runner: {@link MockitoJUnitRunner} or rule:
+ * {@link MockitoRule}.
* <p>
*
*
@@ -782,17 +785,17 @@
* Examples:
* <p>
* <pre class="code"><code class="java">
- * //passes when someMethod() is called within given time span
+ * //passes when someMethod() is called within given time span
* verify(mock, timeout(100)).someMethod();
* //above is an alias to:
* verify(mock, timeout(100).times(1)).someMethod();
- *
+ *
* //passes when someMethod() is called <b>*exactly*</b> 2 times within given time span
* verify(mock, timeout(100).times(2)).someMethod();
*
* //passes when someMethod() is called <b>*at least*</b> 2 times within given time span
* verify(mock, timeout(100).atLeast(2)).someMethod();
- *
+ *
* //verifies someMethod() within given time span using given verification mode
* //useful only if you have your own custom verification modes.
* verify(mock, new Timeout(100, yourOwnVerificationMode)).someMethod();
@@ -801,14 +804,15 @@
*
*
*
- * <h3 id="23">23. (New) <a class="meaningful_link" href="#automatic_instantiation">Automatic instantiation of <code>@Spies</code>,
+ * <h3 id="23">23. <a class="meaningful_link" href="#automatic_instantiation">Automatic instantiation of <code>@Spies</code>,
* <code>@InjectMocks</code></a> and <a class="meaningful_link" href="#constructor_injection">constructor injection goodness</a> (Since 1.9.0)</h3>
*
* <p>
* Mockito will now try to instantiate @{@link Spy} and will instantiate @{@link InjectMocks} fields
* using <b>constructor</b> injection, <b>setter</b> injection, or <b>field</b> injection.
* <p>
- * To take advantage of this feature you need to use {@link MockitoAnnotations#initMocks(Object)} or {@link MockitoJUnitRunner}.
+ * To take advantage of this feature you need to use {@link MockitoAnnotations#initMocks(Object)}, {@link MockitoJUnitRunner}
+ * or {@link MockitoRule}.
* <p>
* Read more about available tricks and the rules of injection in the javadoc for {@link InjectMocks}
* <pre class="code"><code class="java">
@@ -824,7 +828,7 @@
*
*
*
- * <h3 id="24">24. (New) <a class="meaningful_link" href="#one_liner_stub">One-liner stubs</a> (Since 1.9.0)</h3>
+ * <h3 id="24">24. <a class="meaningful_link" href="#one_liner_stub">One-liner stubs</a> (Since 1.9.0)</h3>
* <p>
* Mockito will now allow you to create mocks when stubbing.
* Basically, it allows to create a stub in one line of code.
@@ -840,7 +844,7 @@
*
*
*
- * <h3 id="25">25. (New) <a class="meaningful_link" href="#ignore_stubs_verification">Verification ignoring stubs</a> (Since 1.9.0)</h3>
+ * <h3 id="25">25. <a class="meaningful_link" href="#ignore_stubs_verification">Verification ignoring stubs</a> (Since 1.9.0)</h3>
* <p>
* Mockito will now allow to ignore stubbing for the sake of verification.
* Sometimes useful when coupled with <code>verifyNoMoreInteractions()</code> or verification <code>inOrder()</code>.
@@ -869,7 +873,7 @@
*
*
*
- * <h3 id="26">26. (**New**) <a class="meaningful_link" href="#mocking_details">Mocking details</a> (Since 1.9.5)</h3>
+ * <h3 id="26">26. <a class="meaningful_link" href="#mocking_details">Mocking details</a> (Since 1.9.5)</h3>
* <p>
* To identify whether a particular object is a mock or a spy:
* <pre class="code"><code class="java">
@@ -884,10 +888,13 @@
*
*
*
- * <h3 id="27">27. (**New**) <a class="meaningful_link" href="#delegating_call_to_real_instance">Delegate calls to real instance</a> (Since 1.9.5)</h3>
+ * <h3 id="27">27. <a class="meaningful_link" href="#delegating_call_to_real_instance">Delegate calls to real instance</a> (Since 1.9.5)</h3>
*
* <p>Useful for spies or partial mocks of objects <strong>that are difficult to mock or spy</strong> using the usual spy API.
- * Possible use cases:
+ * Since Mockito 1.10.11, the delegate may or may not be of the same type as the mock.
+ * If the type is different, a matching method needs to be found on delegate type otherwise an exception is thrown.
+ *
+ * Possible use cases for this feature:
* <ul>
* <li>Final classes but with an interface</li>
* <li>Already custom proxied object</li>
@@ -917,7 +924,7 @@
*
*
*
- * <h3 id="28">28. (**New**) <a class="meaningful_link" href="#mock_maker_plugin"><code>MockMaker</code> API</a> (Since 1.9.5)</h3>
+ * <h3 id="28">28. <a class="meaningful_link" href="#mock_maker_plugin"><code>MockMaker</code> API</a> (Since 1.9.5)</h3>
* <p>Driven by requirements and patches from Google Android guys Mockito now offers an extension point
* that allows replacing the proxy generation engine. By default, Mockito uses cglib to create dynamic proxies.
* <p>The extension point is for advanced users that want to extend Mockito. For example, it is now possible
@@ -925,23 +932,59 @@
* <p>For more details, motivations and examples please refer to
* the docs for {@link org.mockito.plugins.MockMaker}.
*
+ *
+ *
+ *
+ * <h3 id="29">29. <a class="meaningful_link" href="#BDD_behavior_verification">(new) BDD style verification</a> (Since 1.10.0)</h3>
+ *
+ * Enables Behavior Driven Development (BDD) style verification by starting verification with the BDD <b>then</b> keyword.
+ *
+ * <pre class="code"><code class="java">
+ * then(person).should(times(2)).ride(bike);
+ * </code></pre>
+ *
+ * For more information and an example see {@link BDDMockito#then(Object)}}
+ *
+ * <h3 id="30">30. <a class="meaningful_link" href="#spying_abstract_classes">(new) Spying or mocking abstract classes (Since 1.10.12)</a></h3>
+ *
+ * It is now possible to conveniently spy on abstract classes. Note that overusing spies hints at code design smells (see {@link #spy(Object)}).
+ * <p>
+ * Previously, spying was only possible on instances of objects.
+ * New API makes it possible to use constructor when creating an instance of the mock.
+ * This is particularly useful for mocking abstract classes because the user is no longer required to provide an instance of the abstract class.
+ * At the moment, only parameter-less constructor is supported, let us know if it is not enough.
+ *
+ * <pre class="code"><code class="java">
+ * //convenience API, new overloaded spy() method:
+ * SomeAbstract spy = spy(SomeAbstract.class);
+ *
+ * //Robust API, via settings builder:
+ * OtherAbstract spy = mock(OtherAbstract.class, withSettings()
+ * .useConstructor().defaultAnswer(CALLS_REAL_METHODS));
+ *
+ * //Mocking a non-static inner abstract class:
+ * InnerAbstract spy = mock(InnerAbstract.class, withSettings()
+ * .useConstructor().outerInstance(outerInstance).defaultAnswer(CALLS_REAL_METHODS));
+ * </code></pre>
+ *
+ * For more information please see {@link MockSettings#useConstructor()}.
*/
@SuppressWarnings("unchecked")
public class Mockito extends Matchers {
-
+
static final MockitoCore MOCKITO_CORE = new MockitoCore();
-
+
/**
* The default <code>Answer</code> of every mock <b>if</b> the mock was not stubbed.
- * Typically it just returns some empty value.
+ * Typically it just returns some empty value.
* <p>
- * {@link Answer} can be used to define the return values of unstubbed invocations.
+ * {@link Answer} can be used to define the return values of unstubbed invocations.
* <p>
- * This implementation first tries the global configuration.
+ * This implementation first tries the global configuration.
* If there is no global configuration then it uses {@link ReturnsEmptyValues} (returns zeros, empty collections, nulls, etc.)
*/
public static final Answer<Object> RETURNS_DEFAULTS = Answers.RETURNS_DEFAULTS.get();
-
+
/**
* Optional <code>Answer</code> to be used with {@link Mockito#mock(Class, Answer)}.
* <p>
@@ -960,26 +1003,26 @@
* Example:
* <pre class="code"><code class="java">
* Foo mock = (Foo.class, RETURNS_SMART_NULLS);
- *
+ *
* //calling unstubbed method here:
* Stuff stuff = mock.getStuff();
- *
+ *
* //using object returned by unstubbed call:
* stuff.doSomething();
- *
+ *
* //Above doesn't yield NullPointerException this time!
- * //Instead, SmartNullPointerException is thrown.
- * //Exception's cause links to unstubbed <i>mock.getStuff()</i> - just click on the stack trace.
+ * //Instead, SmartNullPointerException is thrown.
+ * //Exception's cause links to unstubbed <i>mock.getStuff()</i> - just click on the stack trace.
* </code></pre>
*/
public static final Answer<Object> RETURNS_SMART_NULLS = Answers.RETURNS_SMART_NULLS.get();
-
+
/**
* 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>
- * This implementation can be helpful when working with legacy code.
+ * This implementation can be helpful when working with legacy code.
* <p>
* ReturnsMocks first tries to return ordinary return values (see {@link ReturnsMoreEmptyValues})
* then it tries to return mocks. If the return type cannot be mocked (e.g. is final) then plain null is returned.
@@ -1085,11 +1128,11 @@
* <p>
* As usual you are going to read <b>the partial mock warning</b>:
* Object oriented programming is more less tackling complexity by dividing the complexity into separate, specific, SRPy objects.
- * How does partial mock fit into this paradigm? Well, it just doesn't...
+ * How does partial mock fit into this paradigm? Well, it just doesn't...
* Partial mock usually means that the complexity has been moved to a different method on the same object.
* In most cases, this is not the way you want to design your application.
* <p>
- * However, there are rare cases when partial mocks come handy:
+ * However, there are rare cases when partial mocks come handy:
* dealing with code you cannot change easily (3rd party interfaces, interim refactoring of legacy code etc.)
* However, I wouldn't use partial mocks for new, test-driven & well-designed code.
* <p>
@@ -1112,27 +1155,27 @@
* Creates mock object of given class or interface.
* <p>
* See examples in javadoc for {@link Mockito} class
- *
+ *
* @param classToMock class or interface to mock
* @return mock object
*/
public static <T> T mock(Class<T> classToMock) {
return mock(classToMock, withSettings().defaultAnswer(RETURNS_DEFAULTS));
}
-
+
/**
- * Specifies mock name. Naming mocks can be helpful for debugging - the name is used in all verification errors.
+ * Specifies mock name. Naming mocks can be helpful for debugging - the name is used in all verification errors.
* <p>
- * Beware that naming mocks is not a solution for complex code which uses too many mocks or collaborators.
+ * Beware that naming mocks is not a solution for complex code which uses too many mocks or collaborators.
* <b>If you have too many mocks then refactor the code</b> so that it's easy to test/debug without necessity of naming mocks.
* <p>
* <b>If you use <code>@Mock</code> annotation then you've got naming mocks for free!</b> <code>@Mock</code> uses field name as mock name. {@link Mock Read more.}
* <p>
- *
+ *
* See examples in javadoc for {@link Mockito} class
- *
+ *
* @param classToMock class or interface to mock
- * @param name of the mock
+ * @param name of the mock
* @return mock object
*/
public static <T> T mock(Class<T> classToMock, String name) {
@@ -1149,26 +1192,25 @@
* In future Mockito versions MockingDetails may grow and provide other useful information about the mock,
* e.g. invocations, stubbing info, etc.
*
- * @param toInspect - object to inspect
+ * @param toInspect - object to inspect. null input is allowed.
* @return A {@link org.mockito.MockingDetails} instance.
* @since 1.9.5
*/
- @Incubating
public static MockingDetails mockingDetails(Object toInspect) {
return MOCKITO_CORE.mockingDetails(toInspect);
}
-
+
/**
* <b>Deprecated : Please use mock(Foo.class, defaultAnswer);</b>
* <p>
* See {@link Mockito#mock(Class, Answer)}
* <p>
* Why it is deprecated? ReturnValues is being replaced by Answer
- * for better consistency & interoperability of the framework.
+ * for better consistency & interoperability of the framework.
* Answer interface has been in Mockito for a while and it has the same responsibility as ReturnValues.
* There's no point in mainting exactly the same interfaces.
* <p>
- * Creates mock with a specified strategy for its return values.
+ * Creates mock with a specified strategy for its return values.
* It's quite advanced feature and typically you don't need it to write decent tests.
* However it can be helpful when working with legacy systems.
* <p>
@@ -1176,11 +1218,11 @@
*
* <pre class="code"><code class="java">
* Foo mock = mock(Foo.class, Mockito.RETURNS_SMART_NULLS);
- * Foo mockTwo = mock(Foo.class, new YourOwnReturnValues());
+ * Foo mockTwo = mock(Foo.class, new YourOwnReturnValues());
* </code></pre>
- *
+ *
* <p>See examples in javadoc for {@link Mockito} class</p>
- *
+ *
* @param classToMock class or interface to mock
* @param returnValues default return values for unstubbed methods
*
@@ -1192,9 +1234,9 @@
public static <T> T mock(Class<T> classToMock, ReturnValues returnValues) {
return mock(classToMock, withSettings().defaultAnswer(new AnswerReturnValuesAdapter(returnValues)));
}
-
+
/**
- * Creates mock with a specified strategy for its answers to interactions.
+ * Creates mock with a specified strategy for its answers to interactions.
* It's quite advanced feature and typically you don't need it to write decent tests.
* However it can be helpful when working with legacy systems.
* <p>
@@ -1202,11 +1244,11 @@
*
* <pre class="code"><code class="java">
* Foo mock = mock(Foo.class, RETURNS_SMART_NULLS);
- * Foo mockTwo = mock(Foo.class, new YourOwnAnswer());
+ * Foo mockTwo = mock(Foo.class, new YourOwnAnswer());
* </code></pre>
- *
+ *
* <p>See examples in javadoc for {@link Mockito} class</p>
- *
+ *
* @param classToMock class or interface to mock
* @param defaultAnswer default answer for unstubbed methods
*
@@ -1215,26 +1257,26 @@
public static <T> T mock(Class<T> classToMock, Answer defaultAnswer) {
return mock(classToMock, withSettings().defaultAnswer(defaultAnswer));
}
-
+
/**
* Creates a mock with some non-standard settings.
* <p>
- * The number of configuration points for a mock grows
- * so we need a fluent way to introduce new configuration without adding more and more overloaded Mockito.mock() methods.
+ * The number of configuration points for a mock grows
+ * so we need a fluent way to introduce new configuration without adding more and more overloaded Mockito.mock() methods.
* Hence {@link MockSettings}.
* <pre class="code"><code class="java">
* Listener mock = mock(Listener.class, withSettings()
* .name("firstListner").defaultBehavior(RETURNS_SMART_NULLS));
- * );
+ * );
* </code></pre>
- * <b>Use it carefully and occasionally</b>. What might be reason your test needs non-standard mocks?
- * Is the code under test so complicated that it requires non-standard mocks?
+ * <b>Use it carefully and occasionally</b>. What might be reason your test needs non-standard mocks?
+ * Is the code under test so complicated that it requires non-standard mocks?
* Wouldn't you prefer to refactor the code under test so it is testable in a simple way?
* <p>
* See also {@link Mockito#withSettings()}
* <p>
* See examples in javadoc for {@link Mockito} class
- *
+ *
* @param classToMock class or interface to mock
* @param mockSettings additional mock settings
* @return mock object
@@ -1242,7 +1284,7 @@
public static <T> T mock(Class<T> classToMock, MockSettings mockSettings) {
return MOCKITO_CORE.mock(classToMock, mockSettings);
}
-
+
/**
* Creates a spy of the real object. The spy calls <b>real</b> methods unless they are stubbed.
* <p>
@@ -1250,38 +1292,38 @@
* <p>
* As usual you are going to read <b>the partial mock warning</b>:
* Object oriented programming is more less tackling complexity by dividing the complexity into separate, specific, SRPy objects.
- * How does partial mock fit into this paradigm? Well, it just doesn't...
+ * How does partial mock fit into this paradigm? Well, it just doesn't...
* Partial mock usually means that the complexity has been moved to a different method on the same object.
* In most cases, this is not the way you want to design your application.
* <p>
- * However, there are rare cases when partial mocks come handy:
+ * However, there are rare cases when partial mocks come handy:
* dealing with code you cannot change easily (3rd party interfaces, interim refactoring of legacy code etc.)
* However, I wouldn't use partial mocks for new, test-driven & well-designed code.
* <p>
* Example:
- *
+ *
* <pre class="code"><code class="java">
* List list = new LinkedList();
* List spy = spy(list);
- *
+ *
* //optionally, you can stub out some methods:
* when(spy.size()).thenReturn(100);
- *
+ *
* //using the spy calls <b>real</b> methods
* spy.add("one");
* spy.add("two");
- *
+ *
* //prints "one" - the first element of a list
* System.out.println(spy.get(0));
- *
+ *
* //size() method was stubbed - 100 is printed
* System.out.println(spy.size());
- *
+ *
* //optionally, you can verify
* verify(spy).add("one");
* verify(spy).add("two");
* </code></pre>
- *
+ *
* <h4>Important gotcha on spying real objects!</h4>
* <ol>
* <li>Sometimes it's impossible or impractical to use {@link Mockito#when(Object)} for stubbing spies.
@@ -1313,7 +1355,11 @@
* </ol>
* <p>
* See examples in javadoc for {@link Mockito} class
- *
+ *
+ * <p>Note that the spy won't have any annotations of the spied type, because CGLIB won't rewrite them.
+ * It may troublesome for code that rely on the spy to have these annotations.</p>
+ *
+ *
* @param object
* to spy on
* @return a spy of the real object
@@ -1325,6 +1371,40 @@
}
/**
+ * Please refer to the documentation of {@link #spy(Object)}.
+ * Overusing spies hints at code design smells.
+ * <p>
+ * This method, in contrast to the original {@link #spy(Object)}, creates a spy based on class instead of an object.
+ * Sometimes it is more convenient to create spy based on the class and avoid providing an instance of a spied object.
+ * This is particularly useful for spying on abstract classes because they cannot be instantiated.
+ * See also {@link MockSettings#useConstructor()}.
+ * <p>
+ * Examples:
+ * <pre class="code"><code class="java">
+ * SomeAbstract spy = spy(SomeAbstract.class);
+ *
+ * //Robust API, via settings builder:
+ * OtherAbstract spy = mock(OtherAbstract.class, withSettings()
+ * .useConstructor().defaultAnswer(CALLS_REAL_METHODS));
+ *
+ * //Mocking a non-static inner abstract class:
+ * InnerAbstract spy = mock(InnerAbstract.class, withSettings()
+ * .useConstructor().outerInstance(outerInstance).defaultAnswer(CALLS_REAL_METHODS));
+ * </code></pre>
+ *
+ * @param classToSpy the class to spy
+ * @param <T> type of the spy
+ * @return a spy of the provided class
+ * @since 1.10.12
+ */
+ @Incubating
+ public static <T> T spy(Class<T> classToSpy) {
+ return MOCKITO_CORE.mock(classToSpy, withSettings()
+ .useConstructor()
+ .defaultAnswer(CALLS_REAL_METHODS));
+ }
+
+ /**
* Stubs a method call with return value or an exception. E.g:
*
* <pre class="code"><code class="java">
@@ -1347,7 +1427,7 @@
* <pre class="code"><code class="java">
* //Instead of:
* stub(mock.count()).toReturn(10);
- *
+ *
* //You can do:
* when(mock.count()).thenReturn(10);
* </code></pre>
@@ -1364,11 +1444,11 @@
* the same arguments many times.
* <p>
* Although it is possible to verify a stubbed invocation, usually <b>it's just redundant</b>.
- * Let's say you've stubbed foo.bar().
+ * Let's say you've stubbed foo.bar().
* If your code cares what foo.bar() returns then something else breaks(often before even verify() gets executed).
- * 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>.
- *
+ * 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>.
+ *
* @param methodCall
* method call
* @return DeprecatedOngoingStubbing object to set stubbed value/exception
@@ -1376,16 +1456,16 @@
public static <T> DeprecatedOngoingStubbing<T> stub(T methodCall) {
return MOCKITO_CORE.stub(methodCall);
}
-
+
/**
- * Enables stubbing methods. Use it when you want the mock to return particular value when particular method is called.
+ * Enables stubbing methods. Use it when you want the mock to return particular value when particular method is called.
* <p>
* Simply put: "<b>When</b> the x method is called <b>then</b> return y".
* <p>
* <b>when() is a successor of deprecated {@link Mockito#stub(Object)}</b>
* <p>
* Examples:
- *
+ *
* <pre class="code"><code class="java">
* <b>when</b>(mock.someMethod()).<b>thenReturn</b>(10);
*
@@ -1400,7 +1480,7 @@
* when(mock.someMethod("some arg"))
* .thenThrow(new RuntimeException())
* .thenReturn("foo");
- *
+ *
* //Alternative, shorter version for consecutive stubbing:
* when(mock.someMethod("some arg"))
* .thenReturn("one", "two");
@@ -1412,9 +1492,9 @@
* //shorter version for consecutive method calls throwing exceptions:
* when(mock.someMethod("some arg"))
* .thenThrow(new RuntimeException(), new NullPointerException();
- *
+ *
* </code></pre>
- *
+ *
* For stubbing void methods with throwables see: {@link Mockito#doThrow(Throwable)}
* <p>
* Stubbing can be overridden: for example common stubbing can go to fixture
@@ -1432,7 +1512,7 @@
* 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
* @param methodCall method to be stubbed
@@ -1463,10 +1543,10 @@
* 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
- *
+ *
* @param mock to be verified
* @return mock object itself
*/
@@ -1541,35 +1621,35 @@
* <p>
* Stubbed invocations (if called) are also treated as interactions.
* <p>
- * A word of <b>warning</b>:
+ * A word of <b>warning</b>:
* 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. You can find further reading
+ * 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.
* Consider writing nice code that makes interactions only in test methods.
- *
+ *
* <p>
* Example:
- *
+ *
* <pre class="code"><code class="java">
* //interactions
* mock.doSomething();
* mock.doSomethingUnexpected();
- *
+ *
* //verification
* verify(mock).doSomething();
- *
+ *
* //following will fail because 'doSomethingUnexpected()' is unexpected
* verifyNoMoreInteractions(mock);
- *
+ *
* </code></pre>
- *
+ *
* See examples in javadoc for {@link Mockito} class
- *
+ *
* @param mocks to be verified
*/
public static void verifyNoMoreInteractions(Object... mocks) {
@@ -1581,14 +1661,14 @@
* <pre class="code"><code class="java">
* verifyZeroInteractions(mockOne, mockTwo);
* </code></pre>
- * This method will also detect invocations
+ * This method will also detect invocations
* that occurred before the test method, for example: in <code>setUp()</code>, <code>@Before</code> method or in constructor.
- * Consider writing nice code that makes interactions only in test methods.
+ * Consider writing nice code that makes interactions only in test methods.
* <p>
* See also {@link Mockito#never()} - it is more explicit and communicates the intent well.
* <p>
* See examples in javadoc for {@link Mockito} class
- *
+ *
* @param mocks to be verified
*/
public static void verifyZeroInteractions(Object... mocks) {
@@ -1599,30 +1679,30 @@
* <pre class="code"><code class="java">
* //Instead of:
* stubVoid(mock).toThrow(e).on().someVoidMethod();
- *
+ *
* //Please do:
* doThrow(e).when(mock).someVoidMethod();
* </code></pre>
- *
- * doThrow() replaces stubVoid() because of improved readability and consistency with the family of doAnswer() methods.
+ *
+ * doThrow() replaces stubVoid() because of improved readability and consistency with the family of doAnswer() methods.
* <p>
* Originally, <code>stubVoid()</code> was used for stubbing void methods with exceptions. E.g:
- *
+ *
* <pre class="code"><code class="java">
* stubVoid(mock).toThrow(new RuntimeException()).on().someMethod();
- *
+ *
* //you can stub with different behavior for consecutive calls.
- * //Last stubbing (e.g. toReturn()) determines the behavior for further consecutive calls.
+ * //Last stubbing (e.g. toReturn()) determines the behavior for further consecutive calls.
* stubVoid(mock)
* .toThrow(new RuntimeException())
* .toReturn()
* .on().someMethod();
* </code></pre>
- *
+ *
* See examples in javadoc for {@link Mockito} class
- *
+ *
* @deprecated Use {@link Mockito#doThrow(Throwable)} method for stubbing voids
- *
+ *
* @param mock
* to stub
* @return stubbable object that allows stubbing with throwable
@@ -1630,18 +1710,18 @@
public static <T> VoidMethodStubbable<T> stubVoid(T mock) {
return MOCKITO_CORE.stubVoid(mock);
}
-
+
/**
* Use <code>doThrow()</code> when you want to stub the void method with an exception.
* <p>
* Stubbing voids requires different approach from {@link Mockito#when(Object)} because the compiler does not like void methods inside brackets...
* <p>
* Example:
- *
+ *
* <pre class="code"><code class="java">
* doThrow(new RuntimeException()).when(mock).someVoidMethod();
* </code></pre>
- *
+ *
* @param toBeThrown to be thrown when the stubbed method is called
* @return stubber - to select a method for stubbing
*/
@@ -1676,16 +1756,16 @@
* <p>
* As usual you are going to read <b>the partial mock warning</b>:
* Object oriented programming is more less tackling complexity by dividing the complexity into separate, specific, SRPy objects.
- * How does partial mock fit into this paradigm? Well, it just doesn't...
+ * How does partial mock fit into this paradigm? Well, it just doesn't...
* Partial mock usually means that the complexity has been moved to a different method on the same object.
* In most cases, this is not the way you want to design your application.
* <p>
- * However, there are rare cases when partial mocks come handy:
+ * However, there are rare cases when partial mocks come handy:
* dealing with code you cannot change easily (3rd party interfaces, interim refactoring of legacy code etc.)
* However, I wouldn't use partial mocks for new, test-driven & well-designed code.
* <p>
- * See also javadoc {@link Mockito#spy(Object)} to find out more about partial mocks.
- * <b>Mockito.spy() is a recommended way of creating partial mocks.</b>
+ * See also javadoc {@link Mockito#spy(Object)} to find out more about partial mocks.
+ * <b>Mockito.spy() is a recommended way of creating partial mocks.</b>
* The reason is it guarantees real methods are called against correctly constructed object because you're responsible for constructing the object passed to spy() method.
* <p>
* Example:
@@ -1705,14 +1785,14 @@
public static Stubber doCallRealMethod() {
return MOCKITO_CORE.doAnswer(new CallsRealMethods());
}
-
+
/**
* Use <code>doAnswer()</code> when you want to stub a void method with generic {@link Answer}.
* <p>
* Stubbing voids requires different approach from {@link Mockito#when(Object)} because the compiler does not like void methods inside brackets...
* <p>
* Example:
- *
+ *
* <pre class="code"><code class="java">
* doAnswer(new Answer() {
* public Object answer(InvocationOnMock invocation) {
@@ -1724,17 +1804,17 @@
* </code></pre>
* <p>
* See examples in javadoc for {@link Mockito} class
- *
+ *
* @param answer to answer when the stubbed method is called
* @return stubber - to select a method for stubbing
*/
public static Stubber doAnswer(Answer answer) {
return MOCKITO_CORE.doAnswer(answer);
- }
-
+ }
+
/**
* Use <code>doNothing()</code> for setting void methods to do nothing. <b>Beware that void methods on mocks do nothing by default!</b>
- * However, there are rare situations when doNothing() comes handy:
+ * However, there are rare situations when doNothing() comes handy:
* <p>
* <ol>
* <li>Stubbing consecutive calls on a void method:
@@ -1772,13 +1852,13 @@
*/
public static Stubber doNothing() {
return MOCKITO_CORE.doAnswer(new DoesNothing());
- }
-
+ }
+
/**
* Use <code>doReturn()</code> in those rare occasions when you cannot use {@link Mockito#when(Object)}.
* <p>
- * <b>Beware that {@link Mockito#when(Object)} is always recommended for stubbing because it is argument type-safe
- * and more readable</b> (especially when stubbing consecutive calls).
+ * <b>Beware that {@link Mockito#when(Object)} is always recommended for stubbing because it is argument type-safe
+ * and more readable</b> (especially when stubbing consecutive calls).
* <p>
* Here are those rare occasions when doReturn() comes handy:
* <p>
@@ -1816,39 +1896,39 @@
* overridding stubbing is a potential code smell that points out too much stubbing.
* <p>
* See examples in javadoc for {@link Mockito} class
- *
+ *
* @param toBeReturned to be returned when the stubbed method is called
* @return stubber - to select a method for stubbing
*/
public static Stubber doReturn(Object toBeReturned) {
return MOCKITO_CORE.doAnswer(new Returns(toBeReturned));
}
-
+
/**
* Creates {@link org.mockito.InOrder} object that allows verifying mocks in order.
- *
+ *
* <pre class="code"><code class="java">
* InOrder inOrder = inOrder(firstMock, secondMock);
- *
+ *
* inOrder.verify(firstMock).add("was called first");
* inOrder.verify(secondMock).add("was called second");
* </code></pre>
- *
+ *
* Verification in order is flexible - <b>you don't have to verify all interactions</b> one-by-one
* but only those that you are interested in testing in order.
* <p>
* Also, you can create InOrder object passing only mocks that are relevant for in-order verification.
* <p>
* <code>InOrder</code> verification is 'greedy'. You will hardly every notice it but
- * if you want to find out more search for 'greedy' on the Mockito
- * <a href="http://code.google.com/p/mockito/w/list">wiki pages</a>.
+ * if you want to find out more search for 'greedy' on the Mockito
+ * <a href="http://code.google.com/p/mockito/w/list">wiki pages</a>.
* <p>
* As of Mockito 1.8.4 you can verifyNoMoreInvocations() in order-sensitive way. Read more: {@link InOrder#verifyNoMoreInteractions()}
* <p>
* See examples in javadoc for {@link Mockito} class
- *
+ *
* @param mocks to be verified in order
- *
+ *
* @return InOrder object to be used to verify in order
*/
public static InOrder inOrder(Object... mocks) {
@@ -1927,17 +2007,17 @@
* <pre class="code"><code class="java">
* verify(mock, times(2)).someMethod("some arg");
* </code></pre>
- *
+ *
* See examples in javadoc for {@link Mockito} class
- *
- * @param wantedNumberOfInvocations wanted number of invocations
- *
+ *
+ * @param wantedNumberOfInvocations wanted number of invocations
+ *
* @return verification mode
*/
public static VerificationMode times(int wantedNumberOfInvocations) {
return VerificationModeFactory.times(wantedNumberOfInvocations);
}
-
+
/**
* Alias to <code>times(0)</code>, see {@link Mockito#times(int)}
* <p>
@@ -1945,20 +2025,20 @@
* <pre class="code"><code class="java">
* verify(mock, never()).someMethod();
* </code></pre>
- *
+ *
* <p>
- * If you want to verify there were NO interactions with the mock
+ * If you want to verify there were NO interactions with the mock
* check out {@link Mockito#verifyZeroInteractions(Object...)}
* or {@link Mockito#verifyNoMoreInteractions(Object...)}
* <p>
* See examples in javadoc for {@link Mockito} class
- *
+ *
* @return verification mode
*/
public static VerificationMode never() {
return times(0);
}
-
+
/**
* Allows at-least-once verification. E.g:
* <pre class="code"><code class="java">
@@ -1967,7 +2047,7 @@
* Alias to <code>atLeast(1)</code>.
* <p>
* See examples in javadoc for {@link Mockito} class
- *
+ *
* @return verification mode
*/
public static VerificationMode atLeastOnce() {
@@ -1979,11 +2059,11 @@
* <pre class="code"><code class="java">
* verify(mock, atLeast(3)).someMethod("some arg");
* </code></pre>
- *
+ *
* See examples in javadoc for {@link Mockito} class
- *
- * @param minNumberOfInvocations minimum number of invocations
- *
+ *
+ * @param minNumberOfInvocations minimum number of invocations
+ *
* @return verification mode
*/
public static VerificationMode atLeast(int minNumberOfInvocations) {
@@ -1995,11 +2075,11 @@
* <pre class="code"><code class="java">
* verify(mock, atMost(3)).someMethod("some arg");
* </code></pre>
- *
+ *
* See examples in javadoc for {@link Mockito} class
- *
- * @param maxNumberOfInvocations max number of invocations
- *
+ *
+ * @param maxNumberOfInvocations max number of invocations
+ *
* @return verification mode
*/
public static VerificationMode atMost(int maxNumberOfInvocations) {
@@ -2022,7 +2102,7 @@
public static VerificationMode calls( int wantedNumberOfInvocations ){
return VerificationModeFactory.calls( wantedNumberOfInvocations );
}
-
+
/**
* Allows checking if given method was the only one invoked. E.g:
* <pre class="code"><code class="java">
@@ -2031,89 +2111,135 @@
* verify(mock).someMethod();
* verifyNoMoreInvocations(mock);
* </code></pre>
- *
+ *
* <p>
* See also {@link Mockito#verifyNoMoreInteractions(Object...)}
* <p>
* See examples in javadoc for {@link Mockito} class
- *
+ *
* @return verification mode
*/
public static VerificationMode only() {
return VerificationModeFactory.only();
- }
-
+ }
+
/**
* Allows verifying with timeout. It causes a verify to wait for a specified period of time for a desired
- * interaction rather than fails immediately if had not already happened. May be useful for testing in concurrent
+ * interaction rather than fails immediately if has not already happened. May be useful for testing in concurrent
* conditions.
* <p>
+ * This differs from {@link Mockito#after after()} in that after() will wait the full period, unless
+ * the final test result is known early (e.g. if a never() fails), whereas timeout() will stop early as soon
+ * as verification passes, producing different behaviour when used with times(2), for example, which can pass
+ * and then later fail. In that case, timeout would pass as soon as times(2) passes, whereas after would run until
+ * times(2) failed, and then fail.
+ * <p>
* It feels this feature should be used rarely - figure out a better way of testing your multi-threaded system
* <p>
* Not yet implemented to work with InOrder verification.
* <pre class="code"><code class="java">
- * //passes when someMethod() is called within given time span
+ * //passes when someMethod() is called within given time span
* verify(mock, timeout(100)).someMethod();
* //above is an alias to:
* verify(mock, timeout(100).times(1)).someMethod();
- *
- * //passes when someMethod() is called <b>*exactly*</b> 2 times within given time span
+ *
+ * //passes as soon as someMethod() has been called 2 times before the given timeout
* verify(mock, timeout(100).times(2)).someMethod();
*
- * //passes when someMethod() is called <b>*at least*</b> 2 times within given time span
+ * //equivalent: this also passes as soon as someMethod() has been called 2 times before the given timeout
* verify(mock, timeout(100).atLeast(2)).someMethod();
- *
+ *
* //verifies someMethod() within given time span using given verification mode
* //useful only if you have your own custom verification modes.
* verify(mock, new Timeout(100, yourOwnVerificationMode)).someMethod();
* </code></pre>
- *
+ *
* See examples in javadoc for {@link Mockito} class
- *
- * @param millis - time span in millisecond
- *
+ *
+ * @param millis - time span in milliseconds
+ *
* @return verification mode
*/
- public static VerificationWithTimeout timeout(int millis) {
+ public static VerificationWithTimeout timeout(long millis) {
return new Timeout(millis, VerificationModeFactory.times(1));
- }
-
+ }
+
+ /**
+ * Allows verifying over a given period. It causes a verify to wait for a specified period of time for a desired
+ * interaction rather than failing immediately if has not already happened. May be useful for testing in concurrent
+ * conditions.
+ * <p>
+ * This differs from {@link Mockito#timeout timeout()} in that after() will wait the full period, whereas timeout()
+ * will stop early as soon as verification passes, producing different behaviour when used with times(2), for example,
+ * which can pass and then later fail. In that case, timeout would pass as soon as times(2) passes, whereas after would
+ * run the full time, which point it will fail, as times(2) has failed.
+ * <p>
+ * It feels this feature should be used rarely - figure out a better way of testing your multi-threaded system
+ * <p>
+ * Not yet implemented to work with InOrder verification.
+ * <pre class="code"><code class="java">
+ * //passes after 100ms, if someMethod() has only been called once at that time.
+ * verify(mock, after(100)).someMethod();
+ * //above is an alias to:
+ * verify(mock, after(100).times(1)).someMethod();
+ *
+ * //passes if someMethod() is called <b>*exactly*</b> 2 times after the given timespan
+ * verify(mock, after(100).times(2)).someMethod();
+ *
+ * //passes if someMethod() has not been called after the given timespan
+ * verify(mock, after(100).never()).someMethod();
+ *
+ * //verifies someMethod() after a given time span using given verification mode
+ * //useful only if you have your own custom verification modes.
+ * verify(mock, new After(100, yourOwnVerificationMode)).someMethod();
+ * </code></pre>
+ *
+ * See examples in javadoc for {@link Mockito} class
+ *
+ * @param millis - time span in milliseconds
+ *
+ * @return verification mode
+ */
+ public static VerificationAfterDelay after(int millis) {
+ return new After(millis, VerificationModeFactory.times(1));
+ }
+
/**
* First of all, in case of any trouble, I encourage you to read the Mockito FAQ: <a href="http://code.google.com/p/mockito/wiki/FAQ">http://code.google.com/p/mockito/wiki/FAQ</a>
* <p>
- * In case of questions you may also post to mockito mailing list: <a href="http://groups.google.com/group/mockito">http://groups.google.com/group/mockito</a>
+ * In case of questions you may also post to mockito mailing list: <a href="http://groups.google.com/group/mockito">http://groups.google.com/group/mockito</a>
* <p>
* <code>validateMockitoUsage()</code> <b>explicitly validates</b> the framework state to detect invalid use of Mockito.
* However, this feature is optional <b>because Mockito validates the usage all the time...</b> but there is a gotcha so read on.
* <p>
* Examples of incorrect use:
* <pre class="code"><code class="java">
- * //Oups, someone forgot thenReturn() part:
+ * //Oops, thenReturn() part is missing:
* when(mock.get());
- *
- * //Oups, someone put the verified method call inside verify() where it should be outside:
+ *
+ * //Oops, verified method call is inside verify() where it should be on the outside:
* verify(mock.execute());
- *
- * //Oups, someone has used EasyMock for too long and forgot to specify the method to verify:
+ *
+ * //Oops, missing method to verify:
* verify(mock);
* </code></pre>
- *
- * Mockito throws exceptions if you misuse it so that you know if your tests are written correctly.
- * The gotcha is that Mockito does the validation <b>next time</b> you use the framework (e.g. next time you verify, stub, call mock etc.).
- * But even though the exception might be thrown in the next test,
- * the exception <b>message contains a navigable stack trace element</b> with location of the defect.
+ *
+ * Mockito throws exceptions if you misuse it so that you know if your tests are written correctly.
+ * The gotcha is that Mockito does the validation <b>next time</b> you use the framework (e.g. next time you verify, stub, call mock etc.).
+ * But even though the exception might be thrown in the next test,
+ * the exception <b>message contains a navigable stack trace element</b> with location of the defect.
* Hence you can click and find the place where Mockito was misused.
* <p>
- * Sometimes though, you might want to validate the framework usage explicitly.
+ * Sometimes though, you might want to validate the framework usage explicitly.
* For example, one of the users wanted to put <code>validateMockitoUsage()</code> in his <code>@After</code> method
- * so that he knows immediately when he misused Mockito.
+ * so that he knows immediately when he misused Mockito.
* Without it, he would have known about it not sooner than <b>next time</b> he used the framework.
- * One more benefit of having <code>validateMockitoUsage()</code> in <code>@After</code> is that jUnit runner will always fail in the test method with defect
- * whereas ordinary 'next-time' validation might fail the <b>next</b> test method.
- * But even though JUnit might report next test as red, don't worry about it
- * and just click at navigable stack trace element in the exception message to instantly locate the place where you misused mockito.
+ * One more benefit of having <code>validateMockitoUsage()</code> in <code>@After</code> is that jUnit runner and rule will always fail in the test method with defect
+ * whereas ordinary 'next-time' validation might fail the <b>next</b> test method.
+ * But even though JUnit might report next test as red, don't worry about it
+ * and just click at navigable stack trace element in the exception message to instantly locate the place where you misused mockito.
* <p>
- * <b>Built-in runner: {@link MockitoJUnitRunner}</b> does validateMockitoUsage() after each test method.
+ * <b>Both built-in runner: {@link MockitoJUnitRunner} and rule: {@link MockitoRule}</b> do validateMockitoUsage() after each test method.
* <p>
* Bear in mind that <b>usually you don't have to <code>validateMockitoUsage()</code></b>
* and framework validation triggered on next-time basis should be just enough,
@@ -2128,10 +2254,10 @@
}
/**
- * Allows mock creation with additional mock settings.
+ * Allows mock creation with additional mock settings.
* <p>
- * Don't use it too often.
- * Consider writing simple tests that use simple mocks.
+ * Don't use it too often.
+ * Consider writing simple tests that use simple mocks.
* Repeat after me: simple tests push simple, KISSy, readable & maintainable code.
* If you cannot write a test in a simple way - refactor the code under test.
* <p>
@@ -2141,20 +2267,20 @@
* Foo mock = mock(Foo.class, withSettings()
* .defaultAnswer(RETURNS_SMART_NULLS)
* .name("cool mockie"));
- *
+ *
* //Creates mock with different default answer, descriptive name and extra interfaces
* Foo mock = mock(Foo.class, withSettings()
* .defaultAnswer(RETURNS_SMART_NULLS)
* .name("cool mockie")
- * .extraInterfaces(Bar.class));
+ * .extraInterfaces(Bar.class));
* </code></pre>
- * {@link MockSettings} has been introduced for two reasons.
+ * {@link MockSettings} has been introduced for two reasons.
* Firstly, to make it easy to add another mock settings when the demand comes.
* Secondly, to enable combining different mock settings without introducing zillions of overloaded mock() methods.
* <p>
* See javadoc for {@link MockSettings} to learn about possible mock settings.
* <p>
- *
+ *
* @return mock settings instance with defaults.
*/
public static MockSettings withSettings() {
diff --git a/src/org/mockito/Spy.java b/src/org/mockito/Spy.java
index 5f0d564..ec84c2e 100644
--- a/src/org/mockito/Spy.java
+++ b/src/org/mockito/Spy.java
@@ -1,25 +1,26 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito;
-import java.lang.annotation.*;
-
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
/**
* Allows shorthand wrapping of field instances in an spy object.
- *
+ *
* <p>
* Example:
- *
+ *
* <pre class="code"><code class="java">
* public class Test{
* //Instance for spying is created by calling constructor explicitly:
* @Spy Foo spyOnFoo = new Foo("argument");
- * //Instance for spying is created by mockito via reflection (only default constructors supported):
+ * //Instance for spying is created by mockito via reflection (only default constructors supported):
* @Spy Bar spyOnBar;
* @Before
* public void init(){
@@ -30,7 +31,7 @@
* </code></pre>
* <p>
* Same as doing:
- *
+ *
* <pre class="code"><code class="java">
* Foo spyOnFoo = Mockito.spy(new Foo("argument"));
* Bar spyOnFoo = Mockito.spy(new Bar());
@@ -92,6 +93,9 @@
* {@link org.mockito.runners.MockitoJUnitRunner}.
* </p>
*
+ * <p>Note that the spy won't have any annotations of the spied type, because CGLIB won't rewrite them.
+ * It may troublesome for code that rely on the spy to have these annotations.</p>
+ *
* @see Mockito#spy(Object)
* @see Mock
* @see InjectMocks
diff --git a/src/org/mockito/configuration/DefaultMockitoConfiguration.java b/src/org/mockito/configuration/DefaultMockitoConfiguration.java
index 8fdfc76..626e457 100644
--- a/src/org/mockito/configuration/DefaultMockitoConfiguration.java
+++ b/src/org/mockito/configuration/DefaultMockitoConfiguration.java
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.configuration;
import org.mockito.ReturnValues;
@@ -16,7 +16,7 @@
* <p>
* See javadocs for {@link IMockitoConfiguration} on info how to configure Mockito
*/
-@SuppressWarnings("deprecation")//supressed until ReturnValues are removed
+@SuppressWarnings("deprecation")//suppressed until ReturnValues are removed
public class DefaultMockitoConfiguration implements IMockitoConfiguration {
/* (non-Javadoc)
diff --git a/src/org/mockito/configuration/IMockitoConfiguration.java b/src/org/mockito/configuration/IMockitoConfiguration.java
index 05ecb87..4767d57 100644
--- a/src/org/mockito/configuration/IMockitoConfiguration.java
+++ b/src/org/mockito/configuration/IMockitoConfiguration.java
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.configuration;
import org.mockito.ReturnValues;
@@ -26,7 +26,7 @@
* <p>
* If you have comments on Mockito configuration feature don't hesitate to write to mockito@googlegroups.com
*/
-@SuppressWarnings("deprecation")//supressed until ReturnValues are removed
+@SuppressWarnings("deprecation")//suppressed until ReturnValues are removed
public interface IMockitoConfiguration {
/**
diff --git a/src/org/mockito/exceptions/Reporter.java b/src/org/mockito/exceptions/Reporter.java
index aaa2aff..7ae7588 100644
--- a/src/org/mockito/exceptions/Reporter.java
+++ b/src/org/mockito/exceptions/Reporter.java
@@ -10,6 +10,7 @@
import org.mockito.exceptions.misusing.*;
import org.mockito.exceptions.verification.*;
import org.mockito.internal.debugging.LocationImpl;
+import org.mockito.internal.exceptions.MockitoLimitations;
import org.mockito.internal.exceptions.VerificationAwareInvocation;
import org.mockito.internal.exceptions.util.ScenarioPrinter;
import org.mockito.internal.junit.JUnitTool;
@@ -21,8 +22,10 @@
import org.mockito.invocation.InvocationOnMock;
import org.mockito.invocation.Location;
import org.mockito.listeners.InvocationListener;
+import org.mockito.mock.SerializableMode;
import java.lang.reflect.Field;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -70,6 +73,7 @@
"Hints:",
" 1. missing thenReturn()",
" 2. you are trying to stub a final method, you naughty developer!",
+ " 3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed",
""
));
}
@@ -96,9 +100,8 @@
"Also, this error might show up because:",
"1. you stub either of: final/private/equals()/hashCode() methods.",
" Those methods *cannot* be stubbed/verified.",
+ " " + MockitoLimitations.NON_PUBLIC_PARENT,
"2. inside when() you don't call method on mock but on some other object.",
- "3. the parent of the mocked class is not public.",
- " It is a limitation of the mock engine.",
""
));
}
@@ -113,6 +116,7 @@
"",
"Also, this error might show up because you verify either of: final/private/equals()/hashCode() methods.",
"Those methods *cannot* be stubbed/verified.",
+ MockitoLimitations.NON_PUBLIC_PARENT,
""
));
@@ -137,6 +141,7 @@
" verify(mock).someMethod();",
" verify(mock, times(10)).someMethod();",
" verify(mock, atLeastOnce()).someMethod();",
+ " not: verify(mock.someMethod());",
"Also, if you use @Mock annotation don't miss initMocks()"
));
}
@@ -296,11 +301,7 @@
""
);
- if (JUnitTool.hasJUnit()) {
- throw JUnitTool.createArgumentsAreDifferentException(message, wanted, actual);
- } else {
- throw new ArgumentsAreDifferent(message);
- }
+ throw JUnitTool.createArgumentsAreDifferentException(message, wanted, actual);
}
public void wantedButNotInvoked(DescribedInvocation wanted) {
@@ -419,7 +420,7 @@
throw new NoInteractionsWanted(join(
"No interactions wanted here:",
new LocationImpl(),
- "But found this interaction:",
+ "But found this interaction on mock '" + undesired.getMock() + "':",
undesired.getLocation(),
scenario
));
@@ -429,9 +430,8 @@
throw new VerificationInOrderFailure(join(
"No interactions wanted here:",
new LocationImpl(),
- "But found this interaction:",
- undesired.getLocation(),
- ""
+ "But found this interaction on mock '" + undesired.getMock() + "':",
+ undesired.getLocation()
));
}
@@ -446,7 +446,7 @@
}
public void cannotStubVoidMethodWithAReturnValue(String methodName) {
- throw new MockitoException(join(
+ throw new CannotStubVoidMethodWithReturnValue(join(
"'" + methodName + "' is a *void method* and it *cannot* be stubbed with a *return value*!",
"Voids are usually stubbed with Throwables:",
" doThrow(exception).when(mock).someVoidMethod();",
@@ -457,6 +457,7 @@
"2. Somewhere in your test you are stubbing *final methods*. Sorry, Mockito does not verify/stub final methods.",
"3. A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies - ",
" - with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.",
+ "4. " + MockitoLimitations.NON_PUBLIC_PARENT,
""
));
}
@@ -505,6 +506,7 @@
"",
"Also, this error might show up because you use argument matchers with methods that cannot be mocked.",
"Following methods *cannot* be stubbed/verified: final/private/equals()/hashCode().",
+ MockitoLimitations.NON_PUBLIC_PARENT,
""
));
}
@@ -573,12 +575,12 @@
));
}
- public void cannotCallRealMethodOnInterface() {
+ public void cannotCallAbstractRealMethod() {
throw new MockitoException(join(
- "Cannot call real method on java interface. Interface does not have any implementation!",
- "Calling real methods is only possible when mocking concrete classes.",
+ "Cannot call abstract real method on java object!",
+ "Calling real methods is only possible when mocking non abstract method.",
" //correct example:",
- " when(mockOfConcreteClass.doStuff()).thenCallRealMethod();"
+ " when(mockOfConcreteClass.nonAbstractMethod()).thenCallRealMethod();"
));
}
@@ -626,10 +628,10 @@
""), details);
}
- public void atMostShouldNotBeUsedWithTimeout() {
+ public void atMostAndNeverShouldNotBeUsedWithTimeout() {
throw new FriendlyReminderException(join("",
"Don't panic! I'm just a friendly reminder!",
- "timeout() should not be used with atMost() because...",
+ "timeout() should not be used with atMost() or never() because...",
"...it does not make much sense - the test would have passed immediately in concurency",
"We kept this method only to avoid compilation errors when upgrading Mockito.",
"In future release we will remove timeout(x).atMost(y) from the API.",
@@ -763,4 +765,28 @@
""
));
}
+
+ public void delegatedMethodHasWrongReturnType(Method mockMethod, Method delegateMethod, Object mock, Object delegate) {
+ throw new MockitoException(join(
+ "Methods called on delegated instance must have compatible return types with the mock.",
+ "When calling: " + mockMethod + " on mock: " + new MockUtil().getMockName(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() + ")"
+ ));
+ }
+
+ public void delegatedMethodDoesNotExistOnDelegate(Method mockMethod, Object mock, Object delegate) {
+ throw new MockitoException(join(
+ "Methods called on mock must exist in delegated instance.",
+ "When calling: " + mockMethod + " on mock: " + new MockUtil().getMockName(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() + ")"
+ ));
+ }
+
+ public void usingConstructorWithFancySerializable(SerializableMode mode) {
+ throw new MockitoException("Mocks instantiated with constructor cannot be combined with " + mode + " serialization mode.");
+ }
}
diff --git a/src/org/mockito/exceptions/base/MockitoAssertionError.java b/src/org/mockito/exceptions/base/MockitoAssertionError.java
index 172601e..4da7998 100644
--- a/src/org/mockito/exceptions/base/MockitoAssertionError.java
+++ b/src/org/mockito/exceptions/base/MockitoAssertionError.java
@@ -12,7 +12,7 @@
public class MockitoAssertionError extends AssertionError {
private static final long serialVersionUID = 1L;
- private StackTraceElement[] unfilteredStackTrace;
+ private final StackTraceElement[] unfilteredStackTrace;
public MockitoAssertionError(String message) {
super(message);
diff --git a/src/org/mockito/exceptions/base/MockitoSerializationIssue.java b/src/org/mockito/exceptions/base/MockitoSerializationIssue.java
index b25a431..67a7387 100644
--- a/src/org/mockito/exceptions/base/MockitoSerializationIssue.java
+++ b/src/org/mockito/exceptions/base/MockitoSerializationIssue.java
@@ -18,7 +18,7 @@
* However note that other calls related to the stackTrace will refer to the filter stacktrace.
* </p>
*
- * @since 1.9.6
+ * @since 1.10.0
*/
public class MockitoSerializationIssue extends ObjectStreamException {
diff --git a/src/org/mockito/exceptions/misusing/CannotStubVoidMethodWithReturnValue.java b/src/org/mockito/exceptions/misusing/CannotStubVoidMethodWithReturnValue.java
new file mode 100644
index 0000000..710f1e1
--- /dev/null
+++ b/src/org/mockito/exceptions/misusing/CannotStubVoidMethodWithReturnValue.java
@@ -0,0 +1,9 @@
+package org.mockito.exceptions.misusing;
+
+import org.mockito.exceptions.base.MockitoException;
+
+public class CannotStubVoidMethodWithReturnValue extends MockitoException {
+ public CannotStubVoidMethodWithReturnValue(String message) {
+ super(message);
+ }
+}
diff --git a/src/org/mockito/exceptions/stacktrace/StackTraceCleaner.java b/src/org/mockito/exceptions/stacktrace/StackTraceCleaner.java
index 8e728ac..abd1a32 100644
--- a/src/org/mockito/exceptions/stacktrace/StackTraceCleaner.java
+++ b/src/org/mockito/exceptions/stacktrace/StackTraceCleaner.java
@@ -1,7 +1,5 @@
package org.mockito.exceptions.stacktrace;
-import org.mockito.Incubating;
-
/**
* Decides if particular StackTraceElement is excluded from the human-readable stack trace output.
* Mockito stack trace filtering mechanism uses this information.
@@ -16,7 +14,6 @@
* See the default implementation: {@link org.mockito.internal.exceptions.stacktrace.DefaultStackTraceCleaner}.
*
*/
-@Incubating
public interface StackTraceCleaner {
/**
diff --git a/src/org/mockito/exceptions/verification/junit/ArgumentsAreDifferent.java b/src/org/mockito/exceptions/verification/junit/ArgumentsAreDifferent.java
index 4eb9ea6..cf1321f 100644
--- a/src/org/mockito/exceptions/verification/junit/ArgumentsAreDifferent.java
+++ b/src/org/mockito/exceptions/verification/junit/ArgumentsAreDifferent.java
@@ -14,7 +14,7 @@
private static final long serialVersionUID = 1L;
private final String message;
- private StackTraceElement[] unfilteredStackTrace;
+ private final StackTraceElement[] unfilteredStackTrace;
public ArgumentsAreDifferent(String message, String wanted, String actual) {
super(message, wanted, actual);
diff --git a/src/org/mockito/internal/MockitoCore.java b/src/org/mockito/internal/MockitoCore.java
old mode 100755
new mode 100644
index 49107b8..3ac4e7b
--- a/src/org/mockito/internal/MockitoCore.java
+++ b/src/org/mockito/internal/MockitoCore.java
@@ -1,9 +1,12 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal;
+import java.util.Arrays;
+import java.util.List;
+
import org.mockito.InOrder;
import org.mockito.MockSettings;
import org.mockito.MockingDetails;
@@ -27,22 +30,23 @@
import org.mockito.internal.verification.api.VerificationDataInOrderImpl;
import org.mockito.invocation.Invocation;
import org.mockito.mock.MockCreationSettings;
-import org.mockito.stubbing.*;
+import org.mockito.stubbing.Answer;
+import org.mockito.stubbing.DeprecatedOngoingStubbing;
+import org.mockito.stubbing.OngoingStubbing;
+import org.mockito.stubbing.Stubber;
+import org.mockito.stubbing.VoidMethodStubbable;
import org.mockito.verification.VerificationMode;
-import java.util.Arrays;
-import java.util.List;
-
@SuppressWarnings("unchecked")
public class MockitoCore {
private final Reporter reporter = new Reporter();
private final MockUtil mockUtil = new MockUtil();
private final MockingProgress mockingProgress = new ThreadSafeMockingProgress();
-
- public boolean isTypeMockable(Class<?> typeToMock) {
- return mockUtil.isTypeMockable(typeToMock);
- }
+
+ public boolean isTypeMockable(Class<?> typeToMock) {
+ return mockUtil.isTypeMockable(typeToMock);
+ }
public <T> T mock(Class<T> typeToMock, MockSettings settings) {
if (!MockSettingsImpl.class.isInstance(settings)) {
diff --git a/src/org/mockito/internal/configuration/ClassPathLoader.java b/src/org/mockito/internal/configuration/ClassPathLoader.java
index 43b781b..d31733a 100644
--- a/src/org/mockito/internal/configuration/ClassPathLoader.java
+++ b/src/org/mockito/internal/configuration/ClassPathLoader.java
@@ -54,15 +54,8 @@
* </p>
*/
public class ClassPathLoader {
- private static final String DEFAULT_MOCK_MAKER_CLASS =
- "org.mockito.internal.creation.CglibMockMaker";
- private static final String DEFAULT_STACK_TRACE_CLEANER_PROVIDER_CLASS =
- "org.mockito.internal.exceptions.stacktrace.DefaultStackTraceCleanerProvider";
- public static final String MOCKITO_CONFIGURATION_CLASS_NAME = "org.mockito.configuration.MockitoConfiguration";
- private static final MockMaker mockMaker = findPlatformMockMaker();
- private static final StackTraceCleanerProvider stackTraceCleanerProvider =
- findPlatformStackTraceCleanerProvider();
+ public static final String MOCKITO_CONFIGURATION_CLASS_NAME = "org.mockito.configuration.MockitoConfiguration";
/**
* @return configuration loaded from classpath or null
@@ -86,113 +79,4 @@
throw new MockitoConfigurationException("Unable to instantiate " + MOCKITO_CONFIGURATION_CLASS_NAME +" class. Does it have a safe, no-arg constructor?", e);
}
}
-
- /**
- * Returns the implementation of the mock maker available for the current runtime.
- *
- * <p>Returns {@link org.mockito.internal.creation.CglibMockMaker} if no
- * {@link MockMaker} extension exists or is visible in the current classpath.</p>
- */
- public static MockMaker getMockMaker() {
- return mockMaker;
- }
-
- public static StackTraceCleanerProvider getStackTraceCleanerProvider() {
- //TODO we should throw some sensible exception if this is null.
- return stackTraceCleanerProvider;
- }
-
- /**
- * Scans the classpath to find a mock maker plugin if one is available,
- * allowing mockito to run on alternative platforms like Android.
- */
- static MockMaker findPlatformMockMaker() {
- return findPluginImplementation(MockMaker.class, DEFAULT_MOCK_MAKER_CLASS);
- }
-
- static StackTraceCleanerProvider findPlatformStackTraceCleanerProvider() {
- return findPluginImplementation(
- StackTraceCleanerProvider.class, DEFAULT_STACK_TRACE_CLEANER_PROVIDER_CLASS);
- }
-
- static <T> T findPluginImplementation(Class<T> pluginType, String defaultPluginClassName) {
- for (T plugin : loadImplementations(pluginType)) {
- return plugin; // return the first one service loader finds (if any)
- }
-
- try {
- // Default implementation. Use our own ClassLoader instead of the context
- // ClassLoader, as the default implementation is assumed to be part of
- // Mockito and may not be available via the context ClassLoader.
- return pluginType.cast(Class.forName(defaultPluginClassName).newInstance());
- } catch (Exception e) {
- throw new MockitoException("Internal problem occurred, please report it. " +
- "Mockito is unable to load the default implementation of class that is a part of Mockito distribution. " +
- "Failed to load " + pluginType, e);
- }
- }
-
- /**
- * Equivalent to {@link java.util.ServiceLoader#load} but without requiring
- * Java 6 / Android 2.3 (Gingerbread).
- */
- static <T> List<T> loadImplementations(Class<T> service) {
- ClassLoader loader = Thread.currentThread().getContextClassLoader();
- if (loader == null) {
- loader = ClassLoader.getSystemClassLoader();
- }
- Enumeration<URL> resources;
- try {
- resources = loader.getResources("mockito-extensions/" + service.getName());
- } catch (IOException e) {
- throw new MockitoException("Failed to load " + service, e);
- }
-
- List<T> result = new ArrayList<T>();
- for (URL resource : Collections.list(resources)) {
- InputStream in = null;
- try {
- in = resource.openStream();
- for (String line : readerToLines(new InputStreamReader(in, "UTF-8"))) {
- String name = stripCommentAndWhitespace(line);
- if (name.length() != 0) {
- result.add(service.cast(loader.loadClass(name).newInstance()));
- }
- }
- } catch (Exception e) {
- throw new MockitoConfigurationException(
- "Failed to load " + service + " using " + resource, e);
- } finally {
- closeQuietly(in);
- }
- }
- return result;
- }
-
- static List<String> readerToLines(Reader reader) throws IOException {
- List<String> result = new ArrayList<String>();
- BufferedReader lineReader = new BufferedReader(reader);
- String line;
- while ((line = lineReader.readLine()) != null) {
- result.add(line);
- }
- return result;
- }
-
- static String stripCommentAndWhitespace(String line) {
- int hash = line.indexOf('#');
- if (hash != -1) {
- line = line.substring(0, hash);
- }
- return line.trim();
- }
-
- private static void closeQuietly(InputStream in) {
- if (in != null) {
- try {
- in.close();
- } catch (IOException ignored) {
- }
- }
- }
}
\ No newline at end of file
diff --git a/src/org/mockito/internal/configuration/GlobalConfiguration.java b/src/org/mockito/internal/configuration/GlobalConfiguration.java
index 8adf6ba..99f3dd9 100644
--- a/src/org/mockito/internal/configuration/GlobalConfiguration.java
+++ b/src/org/mockito/internal/configuration/GlobalConfiguration.java
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.configuration;
import org.mockito.ReturnValues;
@@ -15,21 +15,21 @@
/**
* Thread-safe wrapper on user-defined org.mockito.configuration.MockitoConfiguration implementation
*/
-@SuppressWarnings("deprecation")//supressed until ReturnValues are removed
+@SuppressWarnings("deprecation")//suppressed until ReturnValues are removed
public class GlobalConfiguration implements IMockitoConfiguration, Serializable {
- static final long serialVersionUID = -2860353062105505938L;
+ private static final long serialVersionUID = -2860353062105505938L;
- private static ThreadLocal<IMockitoConfiguration> globalConfiguration = new ThreadLocal<IMockitoConfiguration>();
+ private static final ThreadLocal<IMockitoConfiguration> GLOBAL_CONFIGURATION = new ThreadLocal<IMockitoConfiguration>();
//back door for testing
IMockitoConfiguration getIt() {
- return globalConfiguration.get();
+ return GLOBAL_CONFIGURATION.get();
}
public GlobalConfiguration() {
//Configuration should be loaded only once but I cannot really test it
- if (globalConfiguration.get() == null) {
- globalConfiguration.set(createConfig());
+ if (GLOBAL_CONFIGURATION.get() == null) {
+ GLOBAL_CONFIGURATION.set(createConfig());
}
}
@@ -48,22 +48,22 @@
}
public ReturnValues getReturnValues() {
- return globalConfiguration.get().getReturnValues();
+ return GLOBAL_CONFIGURATION.get().getReturnValues();
}
public AnnotationEngine getAnnotationEngine() {
- return globalConfiguration.get().getAnnotationEngine();
+ return GLOBAL_CONFIGURATION.get().getAnnotationEngine();
}
public boolean cleansStackTrace() {
- return globalConfiguration.get().cleansStackTrace();
+ return GLOBAL_CONFIGURATION.get().cleansStackTrace();
}
public boolean enableClassCache() {
- return globalConfiguration.get().enableClassCache();
+ return GLOBAL_CONFIGURATION.get().enableClassCache();
}
public Answer<Object> getDefaultAnswer() {
- return globalConfiguration.get().getDefaultAnswer();
+ return GLOBAL_CONFIGURATION.get().getDefaultAnswer();
}
}
\ No newline at end of file
diff --git a/src/org/mockito/internal/configuration/InjectingAnnotationEngine.java b/src/org/mockito/internal/configuration/InjectingAnnotationEngine.java
index 8a93fa2..530038b 100644
--- a/src/org/mockito/internal/configuration/InjectingAnnotationEngine.java
+++ b/src/org/mockito/internal/configuration/InjectingAnnotationEngine.java
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.configuration;
import org.mockito.*;
@@ -21,8 +21,8 @@
*/
@SuppressWarnings({"deprecation", "unchecked"})
public class InjectingAnnotationEngine implements AnnotationEngine {
- private AnnotationEngine delegate = new DefaultAnnotationEngine();
- private AnnotationEngine spyAnnotationEngine = new SpyAnnotationEngine();
+ private final AnnotationEngine delegate = new DefaultAnnotationEngine();
+ private final AnnotationEngine spyAnnotationEngine = new SpyAnnotationEngine();
/***
* Create a mock using {@link DefaultAnnotationEngine}
diff --git a/src/org/mockito/internal/configuration/SpyAnnotationEngine.java b/src/org/mockito/internal/configuration/SpyAnnotationEngine.java
index de1a195..aef8ceb 100644
--- a/src/org/mockito/internal/configuration/SpyAnnotationEngine.java
+++ b/src/org/mockito/internal/configuration/SpyAnnotationEngine.java
@@ -2,84 +2,128 @@
* Copyright (c) 2007 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
-package org.mockito.internal.configuration;
-
-import org.mockito.*;
-import org.mockito.configuration.AnnotationEngine;
-import org.mockito.exceptions.Reporter;
-import org.mockito.exceptions.base.MockitoException;
-import org.mockito.internal.util.MockUtil;
-import org.mockito.internal.util.reflection.FieldInitializationReport;
-import org.mockito.internal.util.reflection.FieldInitializer;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-
-import static org.mockito.Mockito.withSettings;
-
-/**
- * Process fields annotated with @Spy.
- *
- * <p>
- * Will try transform the field in a spy as with <code>Mockito.spy()</code>.
- * </p>
- *
- * <p>
- * If the field is not initialized, will try to initialize it, with a no-arg constructor.
- * </p>
- *
- * <p>
- * If the field is also annotated with the <strong>compatible</strong> @InjectMocks then the field will be ignored,
- * The injection engine will handle this specific case.
- * </p>
- *
- * <p>This engine will fail, if the field is also annotated with incompatible Mockito annotations.
- */
-@SuppressWarnings({"unchecked"})
-public class SpyAnnotationEngine implements AnnotationEngine {
-
- public Object createMockFor(Annotation annotation, Field field) {
- return null;
- }
-
- @SuppressWarnings("deprecation") // for MockitoAnnotations.Mock
- public void process(Class<?> context, Object testInstance) {
- Field[] fields = context.getDeclaredFields();
- for (Field field : fields) {
- if (field.isAnnotationPresent(Spy.class) && !field.isAnnotationPresent(InjectMocks.class)) {
- assertNoIncompatibleAnnotations(Spy.class, field, Mock.class, org.mockito.MockitoAnnotations.Mock.class, Captor.class);
- Object instance = null;
- try {
- FieldInitializationReport report = new FieldInitializer(testInstance, field).initialize();
- instance = report.fieldInstance();
- } catch (MockitoException e) {
- new Reporter().cannotInitializeForSpyAnnotation(field.getName(), e);
- }
- try {
- if (new MockUtil().isMock(instance)) {
- // instance has been spied earlier
- // for example happens when MockitoAnnotations.initMocks is called two times.
- Mockito.reset(instance);
- } else {
- field.setAccessible(true);
- field.set(testInstance, Mockito.mock(instance.getClass(), withSettings()
- .spiedInstance(instance)
- .defaultAnswer(Mockito.CALLS_REAL_METHODS)
- .name(field.getName())));
- }
- } catch (IllegalAccessException e) {
- throw new MockitoException("Problems initiating spied field " + field.getName(), e);
- }
- }
- }
- }
-
- //TODO duplicated elsewhere
- void assertNoIncompatibleAnnotations(Class annotation, Field field, Class... undesiredAnnotations) {
- for (Class u : undesiredAnnotations) {
- if (field.isAnnotationPresent(u)) {
- new Reporter().unsupportedCombinationOfAnnotations(annotation.getSimpleName(), annotation.getClass().getSimpleName());
- }
- }
- }
-}
+package org.mockito.internal.configuration;
+
+import org.mockito.*;
+import org.mockito.configuration.AnnotationEngine;
+import org.mockito.exceptions.Reporter;
+import org.mockito.exceptions.base.MockitoException;
+import org.mockito.internal.util.MockUtil;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Modifier;
+
+import static org.mockito.Mockito.withSettings;
+
+/**
+ * Process fields annotated with @Spy.
+ * <p/>
+ * <p>
+ * Will try transform the field in a spy as with <code>Mockito.spy()</code>.
+ * </p>
+ * <p/>
+ * <p>
+ * If the field is not initialized, will try to initialize it, with a no-arg constructor.
+ * </p>
+ * <p/>
+ * <p>
+ * If the field is also annotated with the <strong>compatible</strong> @InjectMocks then the field will be ignored,
+ * The injection engine will handle this specific case.
+ * </p>
+ * <p/>
+ * <p>This engine will fail, if the field is also annotated with incompatible Mockito annotations.
+ */
+@SuppressWarnings({"unchecked"})
+public class SpyAnnotationEngine implements AnnotationEngine {
+
+ public Object createMockFor(Annotation annotation, Field field) {
+ return null;
+ }
+
+ @SuppressWarnings("deprecation") // for MockitoAnnotations.Mock
+ public void process(Class<?> context, Object testInstance) {
+ Field[] fields = context.getDeclaredFields();
+ for (Field field : fields) {
+ if (field.isAnnotationPresent(Spy.class) && !field.isAnnotationPresent(InjectMocks.class)) {
+ assertNoIncompatibleAnnotations(Spy.class, field, Mock.class, org.mockito.MockitoAnnotations.Mock.class, Captor.class);
+ field.setAccessible(true);
+ Object instance;
+ try {
+ instance = field.get(testInstance);
+ assertNotInterface(instance, field.getType());
+ if (new MockUtil().isMock(instance)) {
+ // instance has been spied earlier
+ // for example happens when MockitoAnnotations.initMocks is called two times.
+ Mockito.reset(instance);
+ } else if (instance != null) {
+ field.set(testInstance, Mockito.mock(instance.getClass(), withSettings()
+ .spiedInstance(instance)
+ .defaultAnswer(Mockito.CALLS_REAL_METHODS)
+ .name(field.getName())));
+ } else {
+ field.set(testInstance, newSpyInstance(testInstance, field));
+ }
+ } catch (Exception e) {
+ throw new MockitoException("Unable to initialize @Spy annotated field '" + field.getName() + "'.\n" + e.getMessage(), e);
+ }
+ }
+ }
+ }
+
+ private static void assertNotInterface(Object testInstance, Class<?> type) {
+ type = testInstance != null? testInstance.getClass() : type;
+ if (type.isInterface()) {
+ throw new MockitoException("Type '" + type.getSimpleName() + "' is an interface and it cannot be spied on.");
+ }
+ }
+
+ private static Object newSpyInstance(Object testInstance, Field field)
+ throws InstantiationException, IllegalAccessException, InvocationTargetException {
+ MockSettings settings = withSettings()
+ .defaultAnswer(Mockito.CALLS_REAL_METHODS)
+ .name(field.getName());
+ Class<?> type = field.getType();
+ if (type.isInterface()) {
+ return Mockito.mock(type, settings.useConstructor());
+ }
+ if (!Modifier.isStatic(type.getModifiers())) {
+ Class<?> enclosing = type.getEnclosingClass();
+ if (enclosing != null) {
+ if (!enclosing.isInstance(testInstance)) {
+ throw new MockitoException("@Spy annotation can only initialize inner classes declared in the test. "
+ + "Inner class: '" + type.getSimpleName() + "', "
+ + "outer class: '" + enclosing.getSimpleName() + "'.");
+ }
+ return Mockito.mock(type, settings
+ .useConstructor()
+ .outerInstance(testInstance));
+ }
+ }
+ Constructor<?> constructor;
+ try {
+ constructor = type.getDeclaredConstructor();
+ } catch (NoSuchMethodException e) {
+ throw new MockitoException("Please ensure that the type '" + type.getSimpleName() + "' has 0-arg constructor.");
+ }
+
+ if (Modifier.isPrivate(constructor.getModifiers())) {
+ constructor.setAccessible(true);
+ return Mockito.mock(type, settings
+ .spiedInstance(constructor.newInstance()));
+ } else {
+ return Mockito.mock(type, settings.useConstructor());
+ }
+ }
+
+ //TODO duplicated elsewhere
+ void assertNoIncompatibleAnnotations(Class annotation, Field field, Class... undesiredAnnotations) {
+ for (Class u : undesiredAnnotations) {
+ if (field.isAnnotationPresent(u)) {
+ new Reporter().unsupportedCombinationOfAnnotations(annotation.getSimpleName(), annotation.getClass().getSimpleName());
+ }
+ }
+ }
+}
diff --git a/src/org/mockito/internal/configuration/injection/MockInjection.java b/src/org/mockito/internal/configuration/injection/MockInjection.java
index 3418bb6..ef5312c 100644
--- a/src/org/mockito/internal/configuration/injection/MockInjection.java
+++ b/src/org/mockito/internal/configuration/injection/MockInjection.java
@@ -52,11 +52,11 @@
* Ongoing configuration of the mock injector.
*/
public static class OngoingMockInjection {
- private Set<Field> fields = new HashSet<Field>();
- private Set<Object> mocks = newMockSafeHashSet();
- private Object fieldOwner;
- private MockInjectionStrategy injectionStrategies = MockInjectionStrategy.nop();
- private MockInjectionStrategy postInjectionStrategies = MockInjectionStrategy.nop();
+ private final Set<Field> fields = new HashSet<Field>();
+ private final Set<Object> mocks = newMockSafeHashSet();
+ private final Object fieldOwner;
+ private final MockInjectionStrategy injectionStrategies = MockInjectionStrategy.nop();
+ private final MockInjectionStrategy postInjectionStrategies = MockInjectionStrategy.nop();
private OngoingMockInjection(Field field, Object fieldOwner) {
this(Collections.singleton(field), fieldOwner);
diff --git a/src/org/mockito/internal/configuration/injection/PropertyAndSetterInjection.java b/src/org/mockito/internal/configuration/injection/PropertyAndSetterInjection.java
index 2f6ecc6..0fc9f10 100644
--- a/src/org/mockito/internal/configuration/injection/PropertyAndSetterInjection.java
+++ b/src/org/mockito/internal/configuration/injection/PropertyAndSetterInjection.java
@@ -59,9 +59,9 @@
public class PropertyAndSetterInjection extends MockInjectionStrategy {
private final MockCandidateFilter mockCandidateFilter = new TypeBasedCandidateFilter(new NameBasedCandidateFilter(new FinalMockCandidateFilter()));
- private Comparator<Field> superTypesLast = new FieldTypeAndNameComparator();
+ private final Comparator<Field> superTypesLast = new FieldTypeAndNameComparator();
- private ListUtil.Filter<Field> notFinalOrStatic = new ListUtil.Filter<Field>() {
+ private final ListUtil.Filter<Field> notFinalOrStatic = new ListUtil.Filter<Field>() {
public boolean isOut(Field object) {
return Modifier.isFinal(object.getModifiers()) || Modifier.isStatic(object.getModifiers());
}
diff --git a/src/org/mockito/internal/configuration/injection/scanner/MockScanner.java b/src/org/mockito/internal/configuration/injection/scanner/MockScanner.java
index e013627..d7f8941 100644
--- a/src/org/mockito/internal/configuration/injection/scanner/MockScanner.java
+++ b/src/org/mockito/internal/configuration/injection/scanner/MockScanner.java
@@ -19,7 +19,7 @@
* Scan mocks, and prepare them if needed.
*/
public class MockScanner {
- private MockUtil mockUtil = new MockUtil();
+ private final MockUtil mockUtil = new MockUtil();
private final Object instance;
private final Class<?> clazz;
diff --git a/src/org/mockito/internal/configuration/plugins/DefaultPluginSwitch.java b/src/org/mockito/internal/configuration/plugins/DefaultPluginSwitch.java
new file mode 100644
index 0000000..85c9490
--- /dev/null
+++ b/src/org/mockito/internal/configuration/plugins/DefaultPluginSwitch.java
@@ -0,0 +1,9 @@
+package org.mockito.internal.configuration.plugins;
+
+import org.mockito.plugins.PluginSwitch;
+
+class DefaultPluginSwitch implements PluginSwitch {
+ public boolean isEnabled(String pluginClassName) {
+ return true;
+ }
+}
diff --git a/src/org/mockito/internal/configuration/plugins/PluginFileReader.java b/src/org/mockito/internal/configuration/plugins/PluginFileReader.java
new file mode 100644
index 0000000..ec6bda6
--- /dev/null
+++ b/src/org/mockito/internal/configuration/plugins/PluginFileReader.java
@@ -0,0 +1,28 @@
+package org.mockito.internal.configuration.plugins;
+
+import org.mockito.internal.util.io.IOUtil;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+
+class PluginFileReader {
+
+ String readPluginClass(InputStream input) throws IOException {
+ for(String line: IOUtil.readLines(input)) {
+ String stripped = stripCommentAndWhitespace(line);
+ if (stripped.length() > 0) {
+ return stripped;
+ }
+ }
+ return null;
+ }
+
+ private static String stripCommentAndWhitespace(String line) {
+ int hash = line.indexOf('#');
+ if (hash != -1) {
+ line = line.substring(0, hash);
+ }
+ return line.trim();
+ }
+}
diff --git a/src/org/mockito/internal/configuration/plugins/PluginFinder.java b/src/org/mockito/internal/configuration/plugins/PluginFinder.java
new file mode 100644
index 0000000..431c86e
--- /dev/null
+++ b/src/org/mockito/internal/configuration/plugins/PluginFinder.java
@@ -0,0 +1,41 @@
+package org.mockito.internal.configuration.plugins;
+
+import org.mockito.exceptions.base.MockitoException;
+import org.mockito.internal.util.io.IOUtil;
+import org.mockito.plugins.PluginSwitch;
+
+import java.io.InputStream;
+import java.net.URL;
+
+class PluginFinder {
+
+ private final PluginSwitch pluginSwitch;
+
+ public PluginFinder(PluginSwitch pluginSwitch) {
+ this.pluginSwitch = pluginSwitch;
+ }
+
+ String findPluginClass(Iterable<URL> resources) {
+ for (URL resource : resources) {
+ InputStream s = null;
+ try {
+ s = resource.openStream();
+ String pluginClassName = new PluginFileReader().readPluginClass(s);
+ if (pluginClassName == null) {
+ //For backwards compatibility
+ //If the resource does not have plugin class name we're ignoring it
+ continue;
+ }
+ if (!pluginSwitch.isEnabled(pluginClassName)) {
+ continue;
+ }
+ return pluginClassName;
+ } catch(Exception e) {
+ throw new MockitoException("Problems reading plugin implementation from: " + resource, e);
+ } finally {
+ IOUtil.closeQuietly(s);
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/org/mockito/internal/configuration/plugins/PluginLoader.java b/src/org/mockito/internal/configuration/plugins/PluginLoader.java
new file mode 100644
index 0000000..e56fb0e
--- /dev/null
+++ b/src/org/mockito/internal/configuration/plugins/PluginLoader.java
@@ -0,0 +1,70 @@
+package org.mockito.internal.configuration.plugins;
+
+import org.mockito.exceptions.base.MockitoException;
+import org.mockito.exceptions.misusing.MockitoConfigurationException;
+import org.mockito.internal.util.collections.Iterables;
+import org.mockito.plugins.PluginSwitch;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Enumeration;
+
+class PluginLoader {
+
+ private final PluginSwitch pluginSwitch;
+
+ public PluginLoader(PluginSwitch pluginSwitch) {
+ this.pluginSwitch = pluginSwitch;
+ }
+
+ /**
+ * Scans the classpath for given pluginType. If not found, default class is used.
+ */
+ <T> T loadPlugin(Class<T> pluginType, String defaultPluginClassName) {
+ T plugin = loadImpl(pluginType);
+ if (plugin != null) {
+ return plugin;
+ }
+
+ try {
+ // Default implementation. Use our own ClassLoader instead of the context
+ // ClassLoader, as the default implementation is assumed to be part of
+ // Mockito and may not be available via the context ClassLoader.
+ return pluginType.cast(Class.forName(defaultPluginClassName).newInstance());
+ } catch (Exception e) {
+ throw new MockitoException("Internal problem occurred, please report it. " +
+ "Mockito is unable to load the default implementation of class that is a part of Mockito distribution. " +
+ "Failed to load " + pluginType, e);
+ }
+ }
+
+ /**
+ * Equivalent to {@link java.util.ServiceLoader#load} but without requiring
+ * Java 6 / Android 2.3 (Gingerbread).
+ */
+ <T> T loadImpl(Class<T> service) {
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ if (loader == null) {
+ loader = ClassLoader.getSystemClassLoader();
+ }
+ Enumeration<URL> resources;
+ try {
+ resources = loader.getResources("mockito-extensions/" + service.getName());
+ } catch (IOException e) {
+ throw new MockitoException("Failed to load " + service, e);
+ }
+
+ try {
+ String foundPluginClass = new PluginFinder(pluginSwitch).findPluginClass(Iterables.toIterable(resources));
+ if (foundPluginClass != null) {
+ Class<?> pluginClass = loader.loadClass(foundPluginClass);
+ Object plugin = pluginClass.newInstance();
+ return service.cast(plugin);
+ }
+ return null;
+ } catch (Exception e) {
+ throw new MockitoConfigurationException(
+ "Failed to load " + service + " implementation declared in " + resources, e);
+ }
+ }
+}
diff --git a/src/org/mockito/internal/configuration/plugins/PluginRegistry.java b/src/org/mockito/internal/configuration/plugins/PluginRegistry.java
new file mode 100644
index 0000000..7b13973
--- /dev/null
+++ b/src/org/mockito/internal/configuration/plugins/PluginRegistry.java
@@ -0,0 +1,35 @@
+package org.mockito.internal.configuration.plugins;
+
+import org.mockito.plugins.MockMaker;
+import org.mockito.plugins.PluginSwitch;
+import org.mockito.plugins.StackTraceCleanerProvider;
+
+class PluginRegistry {
+
+ private final PluginSwitch pluginSwitch
+ = new PluginLoader(new DefaultPluginSwitch()).loadPlugin(PluginSwitch.class, DefaultPluginSwitch.class.getName());
+
+ private final MockMaker mockMaker
+ = new PluginLoader(pluginSwitch).loadPlugin(MockMaker.class, "org.mockito.internal.creation.cglib.CglibMockMaker");
+
+ private final StackTraceCleanerProvider stackTraceCleanerProvider
+ = new PluginLoader(pluginSwitch).loadPlugin(StackTraceCleanerProvider.class, "org.mockito.internal.exceptions.stacktrace.DefaultStackTraceCleanerProvider");
+
+ /**
+ * The implementation of the stack trace cleaner
+ */
+ StackTraceCleanerProvider getStackTraceCleanerProvider() {
+ //TODO we should throw some sensible exception if this is null.
+ return stackTraceCleanerProvider;
+ }
+
+ /**
+ * Returns the implementation of the mock maker available for the current runtime.
+ *
+ * <p>Returns {@link org.mockito.internal.creation.cglib.CglibMockMaker} if no
+ * {@link org.mockito.plugins.MockMaker} extension exists or is visible in the current classpath.</p>
+ */
+ MockMaker getMockMaker() {
+ return mockMaker;
+ }
+}
diff --git a/src/org/mockito/internal/configuration/plugins/Plugins.java b/src/org/mockito/internal/configuration/plugins/Plugins.java
new file mode 100644
index 0000000..e6a0c7f
--- /dev/null
+++ b/src/org/mockito/internal/configuration/plugins/Plugins.java
@@ -0,0 +1,29 @@
+package org.mockito.internal.configuration.plugins;
+
+import org.mockito.plugins.MockMaker;
+import org.mockito.plugins.StackTraceCleanerProvider;
+
+/**
+ * Access to Mockito behavior that can be reconfigured by plugins
+ */
+public class Plugins {
+
+ private static PluginRegistry registry = new PluginRegistry();
+
+ /**
+ * The implementation of the stack trace cleaner
+ */
+ public static StackTraceCleanerProvider getStackTraceCleanerProvider() {
+ return registry.getStackTraceCleanerProvider();
+ }
+
+ /**
+ * Returns the implementation of the mock maker available for the current runtime.
+ *
+ * <p>Returns {@link org.mockito.internal.creation.cglib.CglibMockMaker} if no
+ * {@link org.mockito.plugins.MockMaker} extension exists or is visible in the current classpath.</p>
+ */
+ public static MockMaker getMockMaker() {
+ return registry.getMockMaker();
+ }
+}
diff --git a/src/org/mockito/internal/creation/AbstractMockitoMethodProxy.java b/src/org/mockito/internal/creation/AbstractMockitoMethodProxy.java
deleted file mode 100644
index a6b6bb0..0000000
--- a/src/org/mockito/internal/creation/AbstractMockitoMethodProxy.java
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
-package org.mockito.internal.creation;
-
-public abstract class AbstractMockitoMethodProxy implements MockitoMethodProxy {
-
- public Object invokeSuper(Object target, Object[] arguments) throws Throwable {
- return getMethodProxy().invokeSuper(target, arguments);
- }
-}
\ No newline at end of file
diff --git a/src/org/mockito/internal/creation/DelegatingMethod.java b/src/org/mockito/internal/creation/DelegatingMethod.java
index e6176f5..034694f 100644
--- a/src/org/mockito/internal/creation/DelegatingMethod.java
+++ b/src/org/mockito/internal/creation/DelegatingMethod.java
@@ -2,52 +2,69 @@
* Copyright (c) 2007 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
-package org.mockito.internal.creation;
-
-import java.lang.reflect.Method;
-
-import org.mockito.internal.invocation.MockitoMethod;
-
-public class DelegatingMethod implements MockitoMethod {
-
- private final Method method;
-
- public DelegatingMethod(Method method) {
- assert method != null : "Method cannot be null";
- this.method = method;
- }
-
- public Class<?>[] getExceptionTypes() {
- return method.getExceptionTypes();
- }
-
- public Method getJavaMethod() {
- return method;
- }
-
- public String getName() {
- return method.getName();
- }
-
- public Class<?>[] getParameterTypes() {
- return method.getParameterTypes();
- }
-
- public Class<?> getReturnType() {
- return method.getReturnType();
- }
-
- public boolean isVarArgs() {
- return method.isVarArgs();
- }
-
- @Override
- public int hashCode() {
- return 1;
- }
-
- @Override
- public boolean equals(Object obj) {
- return method.equals(obj);
- }
+package org.mockito.internal.creation;
+
+import org.mockito.internal.invocation.MockitoMethod;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+public class DelegatingMethod implements MockitoMethod {
+
+ private final Method method;
+
+ public DelegatingMethod(Method method) {
+ assert method != null : "Method cannot be null";
+ this.method = method;
+ }
+
+ public Class<?>[] getExceptionTypes() {
+ return method.getExceptionTypes();
+ }
+
+ public Method getJavaMethod() {
+ return method;
+ }
+
+ public String getName() {
+ return method.getName();
+ }
+
+ public Class<?>[] getParameterTypes() {
+ return method.getParameterTypes();
+ }
+
+ public Class<?> getReturnType() {
+ return method.getReturnType();
+ }
+
+ public boolean isVarArgs() {
+ return method.isVarArgs();
+ }
+
+ public boolean isAbstract() {
+ return (method.getModifiers() & Modifier.ABSTRACT) != 0;
+ }
+
+ /**
+ * @return True if the input object is a DelegatingMethod which has an internal Method which is equal to the internal Method of this DelegatingMethod,
+ * or if the input object is a Method which is equal to the internal Method of this DelegatingMethod.
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o instanceof DelegatingMethod) {
+ DelegatingMethod that = (DelegatingMethod) o;
+ return method.equals(that.method);
+ } else {
+ return method.equals(o);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return method.hashCode();
+ }
}
\ No newline at end of file
diff --git a/src/org/mockito/internal/creation/DelegatingMockitoMethodProxy.java b/src/org/mockito/internal/creation/DelegatingMockitoMethodProxy.java
deleted file mode 100644
index bb2477d..0000000
--- a/src/org/mockito/internal/creation/DelegatingMockitoMethodProxy.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
-package org.mockito.internal.creation;
-
-import org.mockito.cglib.proxy.MethodProxy;
-
-public class DelegatingMockitoMethodProxy extends AbstractMockitoMethodProxy {
-
- private final MethodProxy methodProxy;
-
- public DelegatingMockitoMethodProxy(MethodProxy methodProxy) {
- this.methodProxy = methodProxy;
- }
-
- public MethodProxy getMethodProxy() {
- return methodProxy;
- }
-}
\ No newline at end of file
diff --git a/src/org/mockito/internal/creation/MockSettingsImpl.java b/src/org/mockito/internal/creation/MockSettingsImpl.java
index d226403..c54cffe 100644
--- a/src/org/mockito/internal/creation/MockSettingsImpl.java
+++ b/src/org/mockito/internal/creation/MockSettingsImpl.java
@@ -10,11 +10,10 @@
import org.mockito.internal.debugging.VerboseMockInvocationLogger;
import org.mockito.internal.util.MockCreationValidator;
import org.mockito.internal.util.MockNameImpl;
-import org.mockito.internal.util.MockitoMock;
-import org.mockito.internal.util.MockitoSpy;
import org.mockito.listeners.InvocationListener;
import org.mockito.mock.MockCreationSettings;
import org.mockito.mock.MockName;
+import org.mockito.mock.SerializableMode;
import org.mockito.stubbing.Answer;
import java.io.Serializable;
@@ -28,9 +27,15 @@
public class MockSettingsImpl<T> extends CreationSettings<T> implements MockSettings, MockCreationSettings<T> {
private static final long serialVersionUID = 4475297236197939569L;
+ private boolean useConstructor;
+ private Object outerClassInstance;
public MockSettings serializable() {
- this.serializable = true;
+ return serializable(SerializableMode.BASIC);
+ }
+
+ public MockSettings serializable(SerializableMode mode) {
+ this.serializableMode = mode;
return this;
}
@@ -84,15 +89,29 @@
return defaultAnswer;
}
- public boolean isSerializable() {
- return serializable;
- }
-
public MockSettingsImpl stubOnly() {
this.stubOnly = true;
return this;
}
+ public MockSettings useConstructor() {
+ this.useConstructor = true;
+ return this;
+ }
+
+ public MockSettings outerInstance(Object outerClassInstance) {
+ this.outerClassInstance = outerClassInstance;
+ return this;
+ }
+
+ public boolean isUsingConstructor() {
+ return useConstructor;
+ }
+
+ public Object getOuterClassInstance() {
+ return outerClassInstance;
+ }
+
public boolean isStubOnly() {
return this.stubOnly;
}
@@ -153,7 +172,9 @@
// validator.validateDelegatedInstance(classToMock, settings.getDelegatedInstance());
validator.validateSerializable(typeToMock, source.isSerializable());
+ validator.validateConstructorUse(source.isUsingConstructor(), source.getSerializableMode());
+ //TODO SF - I don't think we really need CreationSettings type
CreationSettings<T> settings = new CreationSettings<T>(source);
settings.setMockName(new MockNameImpl(source.getName(), typeToMock));
settings.setTypeToMock(typeToMock);
@@ -163,13 +184,9 @@
private static Set<Class> prepareExtraInterfaces(CreationSettings settings) {
Set<Class> interfaces = new HashSet<Class>(settings.getExtraInterfaces());
- interfaces.add(MockitoMock.class);
if(settings.isSerializable()) {
interfaces.add(Serializable.class);
}
- if (settings.getSpiedInstance() != null) {
- interfaces.add(MockitoSpy.class);
- }
return interfaces;
}
diff --git a/src/org/mockito/internal/creation/AcrossJVMSerializationFeature.java b/src/org/mockito/internal/creation/cglib/AcrossJVMSerializationFeature.java
similarity index 85%
rename from src/org/mockito/internal/creation/AcrossJVMSerializationFeature.java
rename to src/org/mockito/internal/creation/cglib/AcrossJVMSerializationFeature.java
index 94f6b6f..384f8e6 100644
--- a/src/org/mockito/internal/creation/AcrossJVMSerializationFeature.java
+++ b/src/org/mockito/internal/creation/cglib/AcrossJVMSerializationFeature.java
@@ -3,15 +3,17 @@
* This program is made available under the terms of the MIT License.
*/
-package org.mockito.internal.creation;
+package org.mockito.internal.creation.cglib;
import org.mockito.Incubating;
import org.mockito.exceptions.base.MockitoSerializationIssue;
-import org.mockito.internal.creation.jmock.ClassImposterizer;
+import org.mockito.internal.creation.instance.InstantiatorProvider;
+import org.mockito.internal.creation.settings.CreationSettings;
import org.mockito.internal.util.MockUtil;
import org.mockito.internal.util.reflection.FieldSetter;
import org.mockito.mock.MockCreationSettings;
import org.mockito.mock.MockName;
+import org.mockito.mock.SerializableMode;
import java.io.*;
import java.lang.reflect.Field;
@@ -28,34 +30,35 @@
*
* <p>
* The way it works is to enable serialization via the {@link #enableSerializationAcrossJVM(MockCreationSettings)},
- * if the mock settings is set to be serializable it will add the {@link org.mockito.internal.creation.AcrossJVMSerializationFeature.AcrossJVMMockitoMockSerializable} interface.
- * This interface defines a the {@link org.mockito.internal.creation.AcrossJVMSerializationFeature.AcrossJVMMockitoMockSerializable#writeReplace()}
+ * if the mock settings is set to be serializable it will add the {@link AcrossJVMSerializationFeature.AcrossJVMMockitoMockSerializable}
+ * interface.
+ * This interface defines a the {@link AcrossJVMSerializationFeature.AcrossJVMMockitoMockSerializable#writeReplace()}
* whose signature match the one that is looked by the standard Java serialization.
* </p>
*
* <p>
- * Then in the {@link MethodInterceptorFilter} of mockito, if the <code>writeReplace</code> method is called,
+ * Then in the {@link org.mockito.internal.creation.cglib.MethodInterceptorFilter} of mockito, if the <code>writeReplace</code> method is called,
* it will use the custom implementation of this class {@link #writeReplace(Object)}. This method has a specific
* knowledge on how to serialize a mockito mock that is based on CGLIB.
* </p>
*
- * <p><strong>Only one instance per mock! See {@link MethodInterceptorFilter}</strong></p>
+ * <p><strong>Only one instance per mock! See {@link org.mockito.internal.creation.cglib.MethodInterceptorFilter}</strong></p>
*
* TODO use a proper way to add the interface
* TODO offer a way to disable completely this behavior, or maybe enable this behavior only with a specific setting
* TODO check the class is mockable in the deserialization side
*
- * @see CglibMockMaker
- * @see MethodInterceptorFilter
+ * @see org.mockito.internal.creation.cglib.CglibMockMaker
+ * @see org.mockito.internal.creation.cglib.MethodInterceptorFilter
* @author Brice Dutheil
- * @since 1.9.6
+ * @since 1.10.0
*/
@Incubating
-public class AcrossJVMSerializationFeature implements Serializable {
+class AcrossJVMSerializationFeature implements Serializable {
private static final long serialVersionUID = 7411152578314420778L;
private static final String MOCKITO_PROXY_MARKER = "MockitoProxyMarker";
private boolean instanceLocalCurrentlySerializingFlag = false;
- private Lock mutex = new ReentrantLock();
+ private final Lock mutex = new ReentrantLock();
public boolean isWriteReplace(Method method) {
return method.getReturnType() == Object.class
@@ -76,11 +79,14 @@
* </code></pre>
* So, {@link ObjectOutputStream} will track the <code>writeReplace</code> method in the instance and
* execute it, which is wanted to replace the mock by another type that will encapsulate the actual mock.
- * At this point, the code will return an {@link AcrossJVMMockSerializationProxy}.</p>
+ * At this point, the code will return an
+ * {@link AcrossJVMSerializationFeature.AcrossJVMMockSerializationProxy}.</p>
* </li>
* <li>
- * <p>Now, in the constructor {@link AcrossJVMMockSerializationProxy#AcrossJVMMockSerializationProxy(Object)}
- * the mock is being serialized in a custom way (using {@link MockitoMockObjectOutputStream}) to a
+ * <p>Now, in the constructor
+ * {@link AcrossJVMSerializationFeature.AcrossJVMMockSerializationProxy#AcrossJVMMockSerializationProxy(Object)}
+ * the mock is being serialized in a custom way (using
+ * {@link AcrossJVMSerializationFeature.MockitoMockObjectOutputStream}) to a
* byte array. So basically it means the code is performing double nested serialization of the passed
* <code>mockitoMock</code>.</p>
*
@@ -157,7 +163,7 @@
* @param <T> Type param to not be bothered by the generics
*/
public <T> void enableSerializationAcrossJVM(MockCreationSettings<T> settings) {
- if (settings.isSerializable()) {
+ if (settings.getSerializableMode() == SerializableMode.ACROSS_CLASSLOADERS) {
// havin faith that this set is modifiable
// TODO use a proper way to add the interface
settings.getExtraInterfaces().add(AcrossJVMMockitoMockSerializable.class);
@@ -169,8 +175,9 @@
* This is the serialization proxy that will encapsulate the real mock data as a byte array.
*
* <p>When called in the constructor it will serialize the mock in a byte array using a
- * custom {@link MockitoMockObjectOutputStream} that will annotate the mock class in the stream.
- * other information are used in this class in order to facilitate deserialization.
+ * custom {@link AcrossJVMSerializationFeature.MockitoMockObjectOutputStream} that
+ * will annotate the mock class in the stream.
+ * Other information are used in this class in order to facilitate deserialization.
* </p>
*
* <p>Deserialization of the mock will be performed by the {@link #readResolve()} method via
@@ -180,13 +187,14 @@
private static final long serialVersionUID = -7600267929109286514L;
- private byte[] serializedMock;
- private Class typeToMock;
- private Set<Class> extraInterfaces;
+ private final byte[] serializedMock;
+ private final Class typeToMock;
+ private final Set<Class> extraInterfaces;
/**
* Creates the wrapper that be used in the serialization stream.
*
- * <p>Immediately serializes the Mockito mock using specifically crafted {@link MockitoMockObjectOutputStream},
+ * <p>Immediately serializes the Mockito mock using specifically crafted
+ * {@link AcrossJVMSerializationFeature.MockitoMockObjectOutputStream},
* in a byte array.</p>
*
* @param mockitoMock The Mockito mock to serialize.
@@ -251,20 +259,21 @@
* class. It is doing so via the {@link #resolveClass(java.io.ObjectStreamClass)} which looks in the stream
* for a Mockito marker. If this marker is found it will try to resolve the mockito class otherwise it
* delegates class resolution to the default super behavior.
- * The mirror method used for serializing the mock is {@link MockitoMockObjectOutputStream#annotateClass(Class)}.
+ * The mirror method used for serializing the mock is
+ * {@link AcrossJVMSerializationFeature.MockitoMockObjectOutputStream#annotateClass(Class)}.
* </p>
*
* <p>
- * When this marker is found, {@link ClassImposterizer} methods are being used to create the mock class.
+ * When this marker is found, {@link org.mockito.internal.creation.cglib.ClassImposterizer} methods are being used to create the mock class.
* <em>Note that behind the <code>ClassImposterizer</code> there is CGLIB and the
- * {@link org.mockito.internal.creation.jmock.SearchingClassLoader} that will look if this enhanced class has
+ * {@link org.mockito.internal.creation.util.SearchingClassLoader} that will look if this enhanced class has
* already been created in an accessible classloader ; so basically this code trusts the ClassImposterizer
* code.</em>
* </p>
*/
public static class MockitoMockObjectInputStream extends ObjectInputStream {
- private Class typeToMock;
- private Set<Class> extraInterfaces;
+ private final Class typeToMock;
+ private final Set<Class> extraInterfaces;
public MockitoMockObjectInputStream(InputStream in, Class typeToMock, Set<Class> extraInterfaces) throws IOException {
super(in) ;
@@ -295,8 +304,10 @@
// ClassImposterizer.INSTANCE.canImposterise(typeToMock);
// create the Mockito mock class before it can even be deserialized
- ClassImposterizer.INSTANCE.setConstructorsAccessible(typeToMock, true);
- Class<?> proxyClass = ClassImposterizer.INSTANCE.createProxyClass(
+ //TODO SF unify creation of imposterizer, constructor code duplicated, pulling in CreationSettings internal class
+ ClassImposterizer imposterizer = new ClassImposterizer(new InstantiatorProvider().getInstantiator(new CreationSettings()));
+ imposterizer.setConstructorsAccessible(typeToMock, true);
+ Class<?> proxyClass = imposterizer.createProxyClass(
typeToMock,
extraInterfaces.toArray(new Class[extraInterfaces.size()])
);
@@ -368,7 +379,6 @@
*/
private static class MockitoMockObjectOutputStream extends ObjectOutputStream {
private static final String NOTHING = "";
- private MockUtil mockUtil = new MockUtil();
public MockitoMockObjectOutputStream(ByteArrayOutputStream out) throws IOException {
super(out);
@@ -393,7 +403,7 @@
* @return The marker if this is a Mockito proxy class, otherwise returns a void marker.
*/
private String mockitoProxyClassMarker(Class<?> cl) {
- if (mockUtil.isMock(cl)) {
+ if (AcrossJVMMockitoMockSerializable.class.isAssignableFrom(cl)) {
return MOCKITO_PROXY_MARKER;
} else {
return NOTHING;
diff --git a/src/org/mockito/internal/creation/cglib/CGLIBHacker.java b/src/org/mockito/internal/creation/cglib/CGLIBHacker.java
index e0ce914..6d0abde 100644
--- a/src/org/mockito/internal/creation/cglib/CGLIBHacker.java
+++ b/src/org/mockito/internal/creation/cglib/CGLIBHacker.java
@@ -1,22 +1,18 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.creation.cglib;
+import org.mockito.cglib.proxy.MethodProxy;
+
import java.io.Serializable;
import java.lang.reflect.Field;
-import org.mockito.internal.creation.MockitoMethodProxy;
-import org.mockito.cglib.proxy.MethodProxy;
+class CGLIBHacker {
-public class CGLIBHacker implements Serializable {
-
- private static final long serialVersionUID = -4389233991416356668L;
-
- public void setMockitoNamingPolicy(MockitoMethodProxy mockitoMethodProxy) {
+ public void setMockitoNamingPolicy(MethodProxy methodProxy) {
try {
- MethodProxy methodProxy = mockitoMethodProxy.getMethodProxy();
Field createInfoField = reflectOnCreateInfo(methodProxy);
createInfoField.setAccessible(true);
Object createInfo = createInfoField.get(methodProxy);
diff --git a/src/org/mockito/internal/creation/CglibMockMaker.java b/src/org/mockito/internal/creation/cglib/CglibMockMaker.java
similarity index 87%
rename from src/org/mockito/internal/creation/CglibMockMaker.java
rename to src/org/mockito/internal/creation/cglib/CglibMockMaker.java
index 63893d4..a7025a9 100644
--- a/src/org/mockito/internal/creation/CglibMockMaker.java
+++ b/src/org/mockito/internal/creation/cglib/CglibMockMaker.java
@@ -2,26 +2,26 @@
* Copyright (c) 2007 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
-package org.mockito.internal.creation;
+package org.mockito.internal.creation.cglib;
import org.mockito.cglib.proxy.Callback;
import org.mockito.cglib.proxy.Factory;
import org.mockito.exceptions.base.MockitoException;
import org.mockito.internal.InternalMockHandler;
+import org.mockito.internal.creation.instance.InstantiatorProvider;
import org.mockito.invocation.MockHandler;
import org.mockito.mock.MockCreationSettings;
import org.mockito.plugins.MockMaker;
-import org.mockito.internal.creation.jmock.ClassImposterizer;
/**
* A MockMaker that uses cglib to generate mocks on a JVM.
*/
-public final class CglibMockMaker implements MockMaker {
+public class CglibMockMaker implements MockMaker {
public <T> T createMock(MockCreationSettings<T> settings, MockHandler handler) {
InternalMockHandler mockitoHandler = cast(handler);
new AcrossJVMSerializationFeature().enableSerializationAcrossJVM(settings);
- return ClassImposterizer.INSTANCE.imposterise(
+ return new ClassImposterizer(new InstantiatorProvider().getInstantiator(settings)).imposterise(
new MethodInterceptorFilter(mockitoHandler, settings), settings.getTypeToMock(), settings.getExtraInterfaces());
}
diff --git a/src/org/mockito/internal/creation/jmock/ClassImposterizer.java b/src/org/mockito/internal/creation/cglib/ClassImposterizer.java
similarity index 70%
rename from src/org/mockito/internal/creation/jmock/ClassImposterizer.java
rename to src/org/mockito/internal/creation/cglib/ClassImposterizer.java
index 2e5ebcb..fb2ad95 100644
--- a/src/org/mockito/internal/creation/jmock/ClassImposterizer.java
+++ b/src/org/mockito/internal/creation/cglib/ClassImposterizer.java
@@ -1,148 +1,160 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
-package org.mockito.internal.creation.jmock;
-
-import org.mockito.cglib.core.CodeGenerationException;
-import org.mockito.cglib.core.NamingPolicy;
-import org.mockito.cglib.core.Predicate;
-import org.mockito.cglib.proxy.*;
-import org.mockito.exceptions.base.MockitoException;
-import org.mockito.internal.configuration.GlobalConfiguration;
-import org.mockito.internal.creation.cglib.MockitoNamingPolicy;
-import org.objenesis.ObjenesisStd;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Collection;
-import java.util.List;
-
-import static org.mockito.internal.util.StringJoiner.join;
-
-/**
- * Thanks to jMock guys for this handy class that wraps all the cglib magic.
- */
-public class ClassImposterizer {
-
- public static final ClassImposterizer INSTANCE = new ClassImposterizer();
-
- private ClassImposterizer() {}
-
- //TODO: in order to provide decent exception message when objenesis is not found,
- //have a constructor in this class that tries to instantiate ObjenesisStd and if it fails then show decent exception that dependency is missing
- //TODO: for the same reason catch and give better feedback when hamcrest core is not found.
- private ObjenesisStd objenesis = new ObjenesisStd(new GlobalConfiguration().enableClassCache());
-
- private static final NamingPolicy NAMING_POLICY_THAT_ALLOWS_IMPOSTERISATION_OF_CLASSES_IN_SIGNED_PACKAGES = new MockitoNamingPolicy() {
- @Override
- public String getClassName(String prefix, String source, Object key, Predicate names) {
- return "codegen." + super.getClassName(prefix, source, key, names);
- }
- };
-
- private static final CallbackFilter IGNORE_BRIDGE_METHODS = new CallbackFilter() {
- public int accept(Method method, List<Method> allMethods) {
- return method.isBridge() ? 1 : 0;
- }
- };
-
- public <T> T imposterise(final MethodInterceptor interceptor, Class<T> mockedType, Collection<Class> ancillaryTypes) {
- return imposterise(interceptor, mockedType, ancillaryTypes.toArray(new Class[ancillaryTypes.size()]));
- }
-
- public <T> T imposterise(final MethodInterceptor interceptor, Class<T> mockedType, Class<?>... ancillaryTypes) {
- Class<?> proxyClass = null;
- Object proxyInstance = null;
- try {
- setConstructorsAccessible(mockedType, true);
- proxyClass = createProxyClass(mockedType, ancillaryTypes);
- proxyInstance = createProxy(proxyClass, interceptor);
- return mockedType.cast(proxyInstance);
- } catch (ClassCastException cce) {
- // NPE unlikely to happen because CCE will only happen on the cast statement
- throw new MockitoException(join(
- "ClassCastException occurred while creating the mockito proxy :",
- " class to imposterize : '" + mockedType.getCanonicalName() + "', loaded by classloader : '" + mockedType.getClassLoader() + "'",
- " imposterizing class : '" + proxyClass.getCanonicalName() + "', loaded by classloader : '" + proxyClass.getClassLoader() + "'",
- " proxy instance class : '" + proxyInstance.getClass().getCanonicalName() + "', loaded by classloader : '" + proxyInstance.getClass().getClassLoader() + "'",
- "",
- "You might experience classloading issues, disabling the Objenesis cache *might* help (see MockitoConfiguration)"
- ), cce);
- } finally {
- setConstructorsAccessible(mockedType, false);
- }
- }
-
- public void setConstructorsAccessible(Class<?> mockedType, boolean accessible) {
- for (Constructor<?> constructor : mockedType.getDeclaredConstructors()) {
- constructor.setAccessible(accessible);
- }
- }
-
- public Class<?> createProxyClass(Class<?> mockedType, Class<?>... interfaces) {
- if (mockedType == Object.class) {
- mockedType = ClassWithSuperclassToWorkAroundCglibBug.class;
- }
-
- Enhancer enhancer = new Enhancer() {
- @Override
- @SuppressWarnings("unchecked")
- protected void filterConstructors(Class sc, List constructors) {
- // Don't filter
- }
- };
- enhancer.setClassLoader(SearchingClassLoader.combineLoadersOf(mockedType));
- enhancer.setUseFactory(true);
- if (mockedType.isInterface()) {
- enhancer.setSuperclass(Object.class);
- enhancer.setInterfaces(prepend(mockedType, interfaces));
- } else {
- enhancer.setSuperclass(mockedType);
- enhancer.setInterfaces(interfaces);
- }
- enhancer.setCallbackTypes(new Class[]{MethodInterceptor.class, NoOp.class});
- enhancer.setCallbackFilter(IGNORE_BRIDGE_METHODS);
- if (mockedType.getSigners() != null) {
- enhancer.setNamingPolicy(NAMING_POLICY_THAT_ALLOWS_IMPOSTERISATION_OF_CLASSES_IN_SIGNED_PACKAGES);
- } else {
- enhancer.setNamingPolicy(MockitoNamingPolicy.INSTANCE);
- }
-
- enhancer.setSerialVersionUID(42L);
-
- try {
- return enhancer.createClass();
- } catch (CodeGenerationException e) {
- if (Modifier.isPrivate(mockedType.getModifiers())) {
- throw new MockitoException("\n"
- + "Mockito cannot mock this class: " + mockedType
- + ".\n"
- + "Most likely it is a private class that is not visible by Mockito");
- }
- throw new MockitoException("\n"
- + "Mockito cannot mock this class: " + mockedType
- + "\n"
- + "Mockito can only mock visible & non-final classes."
- + "\n"
- + "If you're not sure why you're getting this error, please report to the mailing list.", e);
- }
- }
-
- private Object createProxy(Class<?> proxyClass, final MethodInterceptor interceptor) {
- Factory proxy = (Factory) objenesis.newInstance(proxyClass);
- proxy.setCallbacks(new Callback[] {interceptor, SerializableNoOp.SERIALIZABLE_INSTANCE });
- return proxy;
- }
-
- private Class<?>[] prepend(Class<?> first, Class<?>... rest) {
- Class<?>[] all = new Class<?>[rest.length+1];
- all[0] = first;
- System.arraycopy(rest, 0, all, 1, rest.length);
- return all;
- }
-
- public static class ClassWithSuperclassToWorkAroundCglibBug {}
-
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
+package org.mockito.internal.creation.cglib;
+
+import org.mockito.cglib.core.CodeGenerationException;
+import org.mockito.cglib.core.NamingPolicy;
+import org.mockito.cglib.core.Predicate;
+import org.mockito.cglib.proxy.*;
+import org.mockito.exceptions.base.MockitoException;
+import org.mockito.internal.creation.instance.InstantationException;
+import org.mockito.internal.creation.instance.Instantiator;
+import org.mockito.internal.creation.util.SearchingClassLoader;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Collection;
+import java.util.List;
+
+import static org.mockito.internal.util.StringJoiner.join;
+
+/**
+ * Inspired on jMock (thanks jMock guys!!!)
+ */
+class ClassImposterizer {
+
+ private final Instantiator instantiator;
+
+ public ClassImposterizer(Instantiator instantiator) {
+ this.instantiator = instantiator;
+ }
+
+ private static final NamingPolicy NAMING_POLICY_THAT_ALLOWS_IMPOSTERISATION_OF_CLASSES_IN_SIGNED_PACKAGES = new MockitoNamingPolicy() {
+ @Override
+ public String getClassName(String prefix, String source, Object key, Predicate names) {
+ return "codegen." + super.getClassName(prefix, source, key, names);
+ }
+ };
+
+ private static final CallbackFilter IGNORE_BRIDGE_METHODS = new CallbackFilter() {
+ public int accept(Method method, List<Method> allMethods) {
+ return method.isBridge() ? 1 : 0;
+ }
+ };
+
+ public <T> T imposterise(final MethodInterceptor interceptor, Class<T> mockedType, Collection<Class> ancillaryTypes) {
+ return (T) imposterise(interceptor, mockedType, ancillaryTypes.toArray(new Class[ancillaryTypes.size()]));
+ }
+
+ public <T> T imposterise(final MethodInterceptor interceptor, Class<T> mockedType, Class<?>... ancillaryTypes) {
+ Class<Factory> proxyClass = null;
+ Object proxyInstance = null;
+ try {
+ setConstructorsAccessible(mockedType, true);
+ proxyClass = createProxyClass(mockedType, ancillaryTypes);
+ proxyInstance = createProxy(proxyClass, interceptor);
+ return mockedType.cast(proxyInstance);
+ } catch (ClassCastException cce) {
+ throw new MockitoException(join(
+ "ClassCastException occurred while creating the mockito proxy :",
+ " class to mock : " + describeClass(mockedType),
+ " created class : " + describeClass(proxyClass),
+ " proxy instance class : " + describeClass(proxyInstance),
+ " instance creation by : " + instantiator.getClass().getSimpleName(),
+ "",
+ "You might experience classloading issues, disabling the Objenesis cache *might* help (see MockitoConfiguration)"
+ ), cce);
+ } finally {
+ setConstructorsAccessible(mockedType, false);
+ }
+ }
+
+ private static String describeClass(Class type) {
+ return type == null? "null" : "'" + type.getCanonicalName() + "', loaded by classloader : '" + type.getClassLoader() + "'";
+ }
+
+ private static String describeClass(Object instance) {
+ return instance == null? "null" : describeClass(instance.getClass());
+ }
+
+ //TODO this method does not belong here
+ public void setConstructorsAccessible(Class<?> mockedType, boolean accessible) {
+ for (Constructor<?> constructor : mockedType.getDeclaredConstructors()) {
+ constructor.setAccessible(accessible);
+ }
+ }
+
+ public Class<Factory> createProxyClass(Class<?> mockedType, Class<?>... interfaces) {
+ if (mockedType == Object.class) {
+ mockedType = ClassWithSuperclassToWorkAroundCglibBug.class;
+ }
+
+ Enhancer enhancer = new Enhancer() {
+ @Override
+ @SuppressWarnings("unchecked")
+ protected void filterConstructors(Class sc, List constructors) {
+ // Don't filter
+ }
+ };
+ Class<?>[] allMockedTypes = prepend(mockedType, interfaces);
+ enhancer.setClassLoader(SearchingClassLoader.combineLoadersOf(allMockedTypes));
+ enhancer.setUseFactory(true);
+ if (mockedType.isInterface()) {
+ enhancer.setSuperclass(Object.class);
+ enhancer.setInterfaces(allMockedTypes);
+ } else {
+ enhancer.setSuperclass(mockedType);
+ enhancer.setInterfaces(interfaces);
+ }
+ enhancer.setCallbackTypes(new Class[]{MethodInterceptor.class, NoOp.class});
+ enhancer.setCallbackFilter(IGNORE_BRIDGE_METHODS);
+ if (mockedType.getSigners() != null) {
+ enhancer.setNamingPolicy(NAMING_POLICY_THAT_ALLOWS_IMPOSTERISATION_OF_CLASSES_IN_SIGNED_PACKAGES);
+ } else {
+ enhancer.setNamingPolicy(MockitoNamingPolicy.INSTANCE);
+ }
+
+ enhancer.setSerialVersionUID(42L);
+
+ try {
+ return enhancer.createClass();
+ } catch (CodeGenerationException e) {
+ if (Modifier.isPrivate(mockedType.getModifiers())) {
+ throw new MockitoException("\n"
+ + "Mockito cannot mock this class: " + mockedType
+ + ".\n"
+ + "Most likely it is a private class that is not visible by Mockito");
+ }
+ throw new MockitoException("\n"
+ + "Mockito cannot mock this class: " + mockedType
+ + "\n"
+ + "Mockito can only mock visible & non-final classes."
+ + "\n"
+ + "If you're not sure why you're getting this error, please report to the mailing list.", e);
+ }
+ }
+
+ private Object createProxy(Class<Factory> proxyClass, final MethodInterceptor interceptor) {
+ Factory proxy;
+ try {
+ proxy = instantiator.newInstance(proxyClass);
+ } catch (InstantationException e) {
+ throw new MockitoException("Unable to create mock instance of type '" + proxyClass.getSuperclass().getSimpleName() + "'", e);
+ }
+ proxy.setCallbacks(new Callback[] {interceptor, SerializableNoOp.SERIALIZABLE_INSTANCE });
+ return proxy;
+ }
+
+ private Class<?>[] prepend(Class<?> first, Class<?>... rest) {
+ Class<?>[] all = new Class<?>[rest.length+1];
+ all[0] = first;
+ System.arraycopy(rest, 0, all, 1, rest.length);
+ return all;
+ }
+
+ public static class ClassWithSuperclassToWorkAroundCglibBug {}
+
}
\ No newline at end of file
diff --git a/src/org/mockito/internal/creation/cglib/DelegatingMockitoMethodProxy.java b/src/org/mockito/internal/creation/cglib/DelegatingMockitoMethodProxy.java
new file mode 100644
index 0000000..9a8e963
--- /dev/null
+++ b/src/org/mockito/internal/creation/cglib/DelegatingMockitoMethodProxy.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
+package org.mockito.internal.creation.cglib;
+
+import org.mockito.cglib.proxy.MethodProxy;
+import org.mockito.internal.creation.util.MockitoMethodProxy;
+
+class DelegatingMockitoMethodProxy implements MockitoMethodProxy {
+
+ private final MethodProxy methodProxy;
+
+ public DelegatingMockitoMethodProxy(MethodProxy methodProxy) {
+ this.methodProxy = methodProxy;
+ }
+
+ public Object invokeSuper(Object target, Object[] arguments) throws Throwable {
+ return methodProxy.invokeSuper(target, arguments);
+ }
+}
\ No newline at end of file
diff --git a/src/org/mockito/internal/creation/MethodInterceptorFilter.java b/src/org/mockito/internal/creation/cglib/MethodInterceptorFilter.java
similarity index 78%
rename from src/org/mockito/internal/creation/MethodInterceptorFilter.java
rename to src/org/mockito/internal/creation/cglib/MethodInterceptorFilter.java
index 3d7d910..bcb2c19 100644
--- a/src/org/mockito/internal/creation/MethodInterceptorFilter.java
+++ b/src/org/mockito/internal/creation/cglib/MethodInterceptorFilter.java
@@ -3,16 +3,17 @@
* This program is made available under the terms of the MIT License.
*/
-package org.mockito.internal.creation;
+package org.mockito.internal.creation.cglib;
import org.mockito.cglib.proxy.MethodInterceptor;
import org.mockito.cglib.proxy.MethodProxy;
import org.mockito.internal.InternalMockHandler;
-import org.mockito.internal.creation.cglib.CGLIBHacker;
+import org.mockito.internal.creation.DelegatingMethod;
+import org.mockito.internal.creation.util.MockitoMethodProxy;
import org.mockito.internal.invocation.InvocationImpl;
import org.mockito.internal.invocation.MockitoMethod;
import org.mockito.internal.invocation.SerializableMethod;
-import org.mockito.internal.invocation.realmethod.FilteredCGLIBProxyRealMethod;
+import org.mockito.internal.invocation.realmethod.CleanTraceRealMethod;
import org.mockito.internal.progress.SequenceNumber;
import org.mockito.internal.util.ObjectMethodsGuru;
import org.mockito.invocation.Invocation;
@@ -24,17 +25,14 @@
/**
* Should be one instance per mock instance, see CglibMockMaker.
- *
- *
*/
-public class MethodInterceptorFilter implements MethodInterceptor, Serializable {
+class MethodInterceptorFilter implements MethodInterceptor, Serializable {
private static final long serialVersionUID = 6182795666612683784L;
private final InternalMockHandler handler;
- CGLIBHacker cglibHacker = new CGLIBHacker();
- ObjectMethodsGuru objectMethodsGuru = new ObjectMethodsGuru();
+ final ObjectMethodsGuru objectMethodsGuru = new ObjectMethodsGuru();
private final MockCreationSettings mockSettings;
- private AcrossJVMSerializationFeature acrossJVMSerializationFeature = new AcrossJVMSerializationFeature();
+ private final AcrossJVMSerializationFeature acrossJVMSerializationFeature = new AcrossJVMSerializationFeature();
public MethodInterceptorFilter(InternalMockHandler handler, MockCreationSettings mockSettings) {
this.handler = handler;
@@ -52,11 +50,11 @@
}
MockitoMethodProxy mockitoMethodProxy = createMockitoMethodProxy(methodProxy);
- cglibHacker.setMockitoNamingPolicy(mockitoMethodProxy);
+ new CGLIBHacker().setMockitoNamingPolicy(methodProxy);
MockitoMethod mockitoMethod = createMockitoMethod(method);
- FilteredCGLIBProxyRealMethod realMethod = new FilteredCGLIBProxyRealMethod(mockitoMethodProxy);
+ CleanTraceRealMethod realMethod = new CleanTraceRealMethod(mockitoMethodProxy);
Invocation invocation = new InvocationImpl(proxy, mockitoMethod, args, SequenceNumber.next(), realMethod);
return handler.handle(invocation);
}
@@ -79,7 +77,7 @@
if (mockSettings.isSerializable()) {
return new SerializableMethod(method);
} else {
- return new DelegatingMethod(method);
+ return new DelegatingMethod(method);
}
}
}
\ No newline at end of file
diff --git a/src/org/mockito/internal/creation/cglib/MockitoNamingPolicy.java b/src/org/mockito/internal/creation/cglib/MockitoNamingPolicy.java
index c646ccd..3ec390c 100644
--- a/src/org/mockito/internal/creation/cglib/MockitoNamingPolicy.java
+++ b/src/org/mockito/internal/creation/cglib/MockitoNamingPolicy.java
@@ -1,12 +1,12 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.creation.cglib;
import org.mockito.cglib.core.DefaultNamingPolicy;
-public class MockitoNamingPolicy extends DefaultNamingPolicy {
+class MockitoNamingPolicy extends DefaultNamingPolicy {
public static final MockitoNamingPolicy INSTANCE = new MockitoNamingPolicy();
diff --git a/src/org/mockito/internal/creation/SerializableMockitoMethodProxy.java b/src/org/mockito/internal/creation/cglib/SerializableMockitoMethodProxy.java
similarity index 67%
rename from src/org/mockito/internal/creation/SerializableMockitoMethodProxy.java
rename to src/org/mockito/internal/creation/cglib/SerializableMockitoMethodProxy.java
index 0646083..7542294 100644
--- a/src/org/mockito/internal/creation/SerializableMockitoMethodProxy.java
+++ b/src/org/mockito/internal/creation/cglib/SerializableMockitoMethodProxy.java
@@ -2,36 +2,43 @@
* Copyright (c) 2007 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
-package org.mockito.internal.creation;
-
-import java.io.Serializable;
-
-import org.mockito.cglib.proxy.MethodProxy;
-import org.mockito.internal.util.reflection.Whitebox;
-
-public class SerializableMockitoMethodProxy extends AbstractMockitoMethodProxy implements Serializable {
-
- private static final long serialVersionUID = -5337859962876770632L;
- private final Class<?> c1;
- private final Class<?> c2;
- private final String desc;
- private final String name;
- private final String superName;
- private transient MethodProxy methodProxy;
-
- public SerializableMockitoMethodProxy(MethodProxy methodProxy) {
- Object info = Whitebox.getInternalState(methodProxy, "createInfo");
- c1 = (Class<?>) Whitebox.getInternalState(info, "c1");
- c2 = (Class<?>) Whitebox.getInternalState(info, "c2");
- desc = methodProxy.getSignature().getDescriptor();
- name = methodProxy.getSignature().getName();
- superName = methodProxy.getSuperName();
- this.methodProxy = methodProxy;
- }
-
- public MethodProxy getMethodProxy() {
- if (methodProxy == null)
- methodProxy = MethodProxy.create(c1, c2, desc, name, superName);
- return methodProxy;
- }
+package org.mockito.internal.creation.cglib;
+
+import org.mockito.cglib.proxy.MethodProxy;
+import org.mockito.internal.creation.util.MockitoMethodProxy;
+import org.mockito.internal.util.reflection.Whitebox;
+
+import java.io.Serializable;
+
+class SerializableMockitoMethodProxy implements MockitoMethodProxy, Serializable {
+
+ private static final long serialVersionUID = -5337859962876770632L;
+ private final Class<?> c1;
+ private final Class<?> c2;
+ private final String desc;
+ private final String name;
+ private final String superName;
+ transient MethodProxy methodProxy;
+
+ public SerializableMockitoMethodProxy(MethodProxy methodProxy) {
+ assert methodProxy != null;
+ Object info = Whitebox.getInternalState(methodProxy, "createInfo");
+ c1 = (Class<?>) Whitebox.getInternalState(info, "c1");
+ c2 = (Class<?>) Whitebox.getInternalState(info, "c2");
+ desc = methodProxy.getSignature().getDescriptor();
+ name = methodProxy.getSignature().getName();
+ superName = methodProxy.getSuperName();
+ this.methodProxy = methodProxy;
+ }
+
+ private MethodProxy getMethodProxy() {
+ if (methodProxy == null) {
+ methodProxy = MethodProxy.create(c1, c2, desc, name, superName);
+ }
+ return methodProxy;
+ }
+
+ public Object invokeSuper(Object target, Object[] arguments) throws Throwable {
+ return getMethodProxy().invokeSuper(target, arguments);
+ }
}
\ No newline at end of file
diff --git a/src/org/mockito/internal/creation/cglib/SerializableNoOp.java b/src/org/mockito/internal/creation/cglib/SerializableNoOp.java
new file mode 100644
index 0000000..807a6eb
--- /dev/null
+++ b/src/org/mockito/internal/creation/cglib/SerializableNoOp.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
+package org.mockito.internal.creation.cglib;
+
+import org.mockito.cglib.proxy.Callback;
+import org.mockito.cglib.proxy.NoOp;
+
+import java.io.Serializable;
+
+/**
+ * Offer a Serializable implementation of the NoOp CGLIB callback.
+ */
+class SerializableNoOp implements NoOp, Serializable {
+
+ private static final long serialVersionUID = 7434976328690189159L;
+ public static final Callback SERIALIZABLE_INSTANCE = new SerializableNoOp();
+
+}
\ No newline at end of file
diff --git a/src/org/mockito/internal/creation/instance/ConstructorInstantiator.java b/src/org/mockito/internal/creation/instance/ConstructorInstantiator.java
new file mode 100644
index 0000000..1832ad3
--- /dev/null
+++ b/src/org/mockito/internal/creation/instance/ConstructorInstantiator.java
@@ -0,0 +1,61 @@
+package org.mockito.internal.creation.instance;
+
+import java.lang.reflect.Constructor;
+
+public class ConstructorInstantiator implements Instantiator {
+
+ private final Object outerClassInstance;
+
+ public ConstructorInstantiator(Object outerClassInstance) {
+ this.outerClassInstance = outerClassInstance;
+ }
+
+ public <T> T newInstance(Class<T> cls) {
+ if (outerClassInstance == null) {
+ return noArgConstructor(cls);
+ }
+ return withParams(cls, outerClassInstance);
+ }
+
+ private static <T> T withParams(Class<T> cls, Object... params) {
+ try {
+ //this is kind of overengineered because we don't need to support more params
+ //however, I know we will be needing it :)
+ for (Constructor<?> constructor : cls.getDeclaredConstructors()) {
+ Class<?>[] types = constructor.getParameterTypes();
+ if (paramsMatch(types, params)) {
+ return (T) constructor.newInstance(params);
+ }
+ }
+ } catch (Exception e) {
+ throw paramsException(cls, e);
+ }
+ throw paramsException(cls, null);
+ }
+
+ private static <T> InstantationException paramsException(Class<T> cls, Exception e) {
+ return new InstantationException("Unable to create instance of '"
+ + cls.getSimpleName() + "'.\nPlease ensure that the outer instance has correct type and that the target class has 0-arg constructor.", e);
+ }
+
+ private static boolean paramsMatch(Class<?>[] types, Object[] params) {
+ if (params.length != types.length) {
+ return false;
+ }
+ for (int i = 0; i < params.length; i++) {
+ if (!types[i].isInstance(params[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static <T> T noArgConstructor(Class<T> cls) {
+ try {
+ return cls.newInstance();
+ } catch (Throwable t) {
+ throw new InstantationException("Unable to create instance of '"
+ + cls.getSimpleName() + "'.\nPlease ensure it has 0-arg constructor which invokes cleanly.", t);
+ }
+ }
+}
diff --git a/src/org/mockito/internal/creation/instance/InstantationException.java b/src/org/mockito/internal/creation/instance/InstantationException.java
new file mode 100644
index 0000000..751f999
--- /dev/null
+++ b/src/org/mockito/internal/creation/instance/InstantationException.java
@@ -0,0 +1,10 @@
+package org.mockito.internal.creation.instance;
+
+import org.mockito.exceptions.base.MockitoException;
+
+public class InstantationException extends MockitoException {
+
+ public InstantationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/src/org/mockito/internal/creation/instance/Instantiator.java b/src/org/mockito/internal/creation/instance/Instantiator.java
new file mode 100644
index 0000000..ecb788d
--- /dev/null
+++ b/src/org/mockito/internal/creation/instance/Instantiator.java
@@ -0,0 +1,13 @@
+package org.mockito.internal.creation.instance;
+
+/**
+ * Provides instances of classes.
+ */
+public interface Instantiator {
+
+ /**
+ * Creates instance of given class
+ */
+ <T> T newInstance(Class<T> cls) throws InstantationException;
+
+}
diff --git a/src/org/mockito/internal/creation/instance/InstantiatorProvider.java b/src/org/mockito/internal/creation/instance/InstantiatorProvider.java
new file mode 100644
index 0000000..58dc6c1
--- /dev/null
+++ b/src/org/mockito/internal/creation/instance/InstantiatorProvider.java
@@ -0,0 +1,16 @@
+package org.mockito.internal.creation.instance;
+
+import org.mockito.mock.MockCreationSettings;
+
+public class InstantiatorProvider {
+
+ private final static Instantiator INSTANCE = new ObjenesisInstantiator();
+
+ public Instantiator getInstantiator(MockCreationSettings settings) {
+ if (settings.isUsingConstructor()) {
+ return new ConstructorInstantiator(settings.getOuterClassInstance());
+ } else {
+ return INSTANCE;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/org/mockito/internal/creation/instance/ObjenesisInstantiator.java b/src/org/mockito/internal/creation/instance/ObjenesisInstantiator.java
new file mode 100644
index 0000000..15172bd
--- /dev/null
+++ b/src/org/mockito/internal/creation/instance/ObjenesisInstantiator.java
@@ -0,0 +1,16 @@
+package org.mockito.internal.creation.instance;
+
+import org.mockito.internal.configuration.GlobalConfiguration;
+import org.objenesis.ObjenesisStd;
+
+class ObjenesisInstantiator implements Instantiator {
+
+ //TODO: in order to provide decent exception message when objenesis is not found,
+ //have a constructor in this class that tries to instantiate ObjenesisStd and if it fails then show decent exception that dependency is missing
+ //TODO: for the same reason catch and give better feedback when hamcrest core is not found.
+ private final ObjenesisStd objenesis = new ObjenesisStd(new GlobalConfiguration().enableClassCache());
+
+ public <T> T newInstance(Class<T> cls) {
+ return (T) objenesis.newInstance(cls);
+ }
+}
diff --git a/src/org/mockito/internal/creation/jmock/SerializableNoOp.java b/src/org/mockito/internal/creation/jmock/SerializableNoOp.java
deleted file mode 100644
index c5608e7..0000000
--- a/src/org/mockito/internal/creation/jmock/SerializableNoOp.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
-package org.mockito.internal.creation.jmock;
-
-import org.mockito.cglib.proxy.Callback;
-import org.mockito.cglib.proxy.NoOp;
-
-import java.io.Serializable;
-
-/**
- * Offer a Serializable implementation of the NoOp CGLIB callback.
- */
-public class SerializableNoOp implements NoOp, Serializable {
-
- private static final long serialVersionUID = 7434976328690189159L;
- public static final Callback SERIALIZABLE_INSTANCE = new SerializableNoOp();
-
-}
diff --git a/src/org/mockito/internal/creation/jmock/jmock-license.txt b/src/org/mockito/internal/creation/jmock/jmock-license.txt
deleted file mode 100644
index 4c56c9c..0000000
--- a/src/org/mockito/internal/creation/jmock/jmock-license.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2000-2007, jMock.org
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-Redistributions of source code must retain the above copyright notice, this list of
-conditions and the following disclaimer. Redistributions in binary form must reproduce
-the above copyright notice, this list of conditions and the following disclaimer in
-the documentation and/or other materials provided with the distribution.
-
-Neither the name of jMock nor the names of its contributors may be used to endorse
-or promote products derived from this software without specific prior written
-permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
-EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
-WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGE.
\ No newline at end of file
diff --git a/src/org/mockito/internal/creation/settings/CreationSettings.java b/src/org/mockito/internal/creation/settings/CreationSettings.java
index 94d8dc6..52e6d19 100644
--- a/src/org/mockito/internal/creation/settings/CreationSettings.java
+++ b/src/org/mockito/internal/creation/settings/CreationSettings.java
@@ -7,6 +7,7 @@
import org.mockito.listeners.InvocationListener;
import org.mockito.mock.MockCreationSettings;
import org.mockito.mock.MockName;
+import org.mockito.mock.SerializableMode;
import org.mockito.stubbing.Answer;
import java.io.Serializable;
@@ -27,9 +28,11 @@
protected Object spiedInstance;
protected Answer<Object> defaultAnswer;
protected MockName mockName;
- protected boolean serializable;
+ protected SerializableMode serializableMode = SerializableMode.NONE;
protected List<InvocationListener> invocationListeners = new ArrayList<InvocationListener>();
protected boolean stubOnly;
+ private boolean useConstructor;
+ private Object outerClassInstance;
public CreationSettings() {}
@@ -41,9 +44,11 @@
this.spiedInstance = copy.spiedInstance;
this.defaultAnswer = copy.defaultAnswer;
this.mockName = copy.mockName;
- this.serializable = copy.serializable;
+ this.serializableMode = copy.serializableMode;
this.invocationListeners = copy.invocationListeners;
this.stubOnly = copy.stubOnly;
+ this.useConstructor = copy.isUsingConstructor();
+ this.outerClassInstance = copy.getOuterClassInstance();
}
public Class<T> getTypeToMock() {
@@ -86,13 +91,25 @@
}
public boolean isSerializable() {
- return serializable;
+ return serializableMode != SerializableMode.NONE;
+ }
+
+ public SerializableMode getSerializableMode() {
+ return serializableMode;
}
public List<InvocationListener> getInvocationListeners() {
return invocationListeners;
}
+ public boolean isUsingConstructor() {
+ return useConstructor;
+ }
+
+ public Object getOuterClassInstance() {
+ return outerClassInstance;
+ }
+
public boolean isStubOnly() {
return stubOnly;
}
diff --git a/src/org/mockito/internal/creation/MockitoMethodProxy.java b/src/org/mockito/internal/creation/util/MockitoMethodProxy.java
similarity index 66%
rename from src/org/mockito/internal/creation/MockitoMethodProxy.java
rename to src/org/mockito/internal/creation/util/MockitoMethodProxy.java
index 384ca61..77ec6d1 100644
--- a/src/org/mockito/internal/creation/MockitoMethodProxy.java
+++ b/src/org/mockito/internal/creation/util/MockitoMethodProxy.java
@@ -2,14 +2,9 @@
* Copyright (c) 2007 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
-package org.mockito.internal.creation;
-
-import org.mockito.cglib.proxy.MethodProxy;
-
-public interface MockitoMethodProxy {
-
- Object invokeSuper(Object target, Object[] arguments) throws Throwable;
-
- MethodProxy getMethodProxy();
-
+package org.mockito.internal.creation.util;
+
+//TODO SF Replace with RealMethod and get rid of (possibly).
+public interface MockitoMethodProxy {
+ Object invokeSuper(Object target, Object[] arguments) throws Throwable;
}
\ No newline at end of file
diff --git a/src/org/mockito/internal/creation/jmock/SearchingClassLoader.java b/src/org/mockito/internal/creation/util/SearchingClassLoader.java
similarity index 86%
rename from src/org/mockito/internal/creation/jmock/SearchingClassLoader.java
rename to src/org/mockito/internal/creation/util/SearchingClassLoader.java
index 85d741e..62bd0e4 100644
--- a/src/org/mockito/internal/creation/jmock/SearchingClassLoader.java
+++ b/src/org/mockito/internal/creation/util/SearchingClassLoader.java
@@ -2,75 +2,75 @@
* Copyright (c) 2007 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
-package org.mockito.internal.creation.jmock;
-
-import static java.lang.Thread.*;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Thanks to jMock guys for this ClassLoader.
- */
-public class SearchingClassLoader extends ClassLoader {
- private final ClassLoader nextToSearch;
-
- public SearchingClassLoader(ClassLoader parent, ClassLoader nextToSearch) {
- super(parent);
- this.nextToSearch = nextToSearch;
- }
-
- public static ClassLoader combineLoadersOf(Class<?>... classes) {
- return combineLoadersOf(classes[0], classes);
- }
-
- private static ClassLoader combineLoadersOf(Class<?> first, Class<?>... others) {
- List<ClassLoader> loaders = new ArrayList<ClassLoader>();
-
- addIfNewElement(loaders, first.getClassLoader());
- for (Class<?> c : others) {
- addIfNewElement(loaders, c.getClassLoader());
- }
-
- // To support Eclipse Plug-in tests.
- // In an Eclipse plug-in, jMock itself will not be on the system class loader
- // but in the class loader of the plug-in.
- //
- // Note: I've been unable to reproduce the error in jMock's test suite.
- addIfNewElement(loaders, SearchingClassLoader.class.getClassLoader());
-
- // To support the Maven Surefire plugin.
- // Note: I've been unable to reproduce the error in jMock's test suite.
- addIfNewElement(loaders, currentThread().getContextClassLoader());
-
- //Had to comment that out because it didn't work with in-container Spring tests
- //addIfNewElement(loaders, ClassLoader.getSystemClassLoader());
-
- return combine(loaders);
- }
-
- private static ClassLoader combine(List<ClassLoader> parentLoaders) {
- ClassLoader loader = parentLoaders.get(parentLoaders.size()-1);
-
- for (int i = parentLoaders.size()-2; i >= 0; i--) {
- loader = new SearchingClassLoader(parentLoaders.get(i), loader);
- }
-
- return loader;
- }
-
- private static void addIfNewElement(List<ClassLoader> loaders, ClassLoader c) {
- if (c != null && !loaders.contains(c)) {
- loaders.add(c);
- }
- }
-
- @Override
- protected Class<?> findClass(String name) throws ClassNotFoundException {
- if (nextToSearch != null) {
- return nextToSearch.loadClass(name);
- } else {
- return super.findClass(name); // will throw ClassNotFoundException
- }
- }
+package org.mockito.internal.creation.util;
+
+import static java.lang.Thread.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Inspired on jMock (thanks jMock guys!!!)
+ */
+public class SearchingClassLoader extends ClassLoader {
+ private final ClassLoader nextToSearch;
+
+ public SearchingClassLoader(ClassLoader parent, ClassLoader nextToSearch) {
+ super(parent);
+ this.nextToSearch = nextToSearch;
+ }
+
+ public static ClassLoader combineLoadersOf(Class<?>... classes) {
+ return combineLoadersOf(classes[0], classes);
+ }
+
+ private static ClassLoader combineLoadersOf(Class<?> first, Class<?>... others) {
+ List<ClassLoader> loaders = new ArrayList<ClassLoader>();
+
+ addIfNewElement(loaders, first.getClassLoader());
+ for (Class<?> c : others) {
+ addIfNewElement(loaders, c.getClassLoader());
+ }
+
+ // To support Eclipse Plug-in tests.
+ // In an Eclipse plug-in, we will not be on the system class loader
+ // but in the class loader of the plug-in.
+ //
+ // Note: I've been unable to reproduce the error in the test suite.
+ addIfNewElement(loaders, SearchingClassLoader.class.getClassLoader());
+
+ // To support the Maven Surefire plugin.
+ // Note: I've been unable to reproduce the error in the test suite.
+ addIfNewElement(loaders, currentThread().getContextClassLoader());
+
+ //Had to comment that out because it didn't work with in-container Spring tests
+ //addIfNewElement(loaders, ClassLoader.getSystemClassLoader());
+
+ return combine(loaders);
+ }
+
+ private static ClassLoader combine(List<ClassLoader> parentLoaders) {
+ ClassLoader loader = parentLoaders.get(parentLoaders.size()-1);
+
+ for (int i = parentLoaders.size()-2; i >= 0; i--) {
+ loader = new SearchingClassLoader(parentLoaders.get(i), loader);
+ }
+
+ return loader;
+ }
+
+ private static void addIfNewElement(List<ClassLoader> loaders, ClassLoader c) {
+ if (c != null && !loaders.contains(c)) {
+ loaders.add(c);
+ }
+ }
+
+ @Override
+ protected Class<?> findClass(String name) throws ClassNotFoundException {
+ if (nextToSearch != null) {
+ return nextToSearch.loadClass(name);
+ } else {
+ return super.findClass(name); // will throw ClassNotFoundException
+ }
+ }
}
\ No newline at end of file
diff --git a/src/org/mockito/internal/creation/jmock/package.html b/src/org/mockito/internal/creation/util/package.html
similarity index 69%
rename from src/org/mockito/internal/creation/jmock/package.html
rename to src/org/mockito/internal/creation/util/package.html
index 39c142b..fb6ba2d 100644
--- a/src/org/mockito/internal/creation/jmock/package.html
+++ b/src/org/mockito/internal/creation/util/package.html
@@ -2,5 +2,4 @@
~ Copyright (c) 2007 Mockito contributors
~ This program is made available under the terms of the MIT License.
-->
-
-<body>Borrowed from jmock codebase</body>
\ No newline at end of file
+<body>Stuff that does not have a good package yet</body>
\ No newline at end of file
diff --git a/src/org/mockito/internal/debugging/LoggingListener.java b/src/org/mockito/internal/debugging/LoggingListener.java
index 99f6638..e31a5bb 100644
--- a/src/org/mockito/internal/debugging/LoggingListener.java
+++ b/src/org/mockito/internal/debugging/LoggingListener.java
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.debugging;
import org.mockito.internal.invocation.InvocationMatcher;
@@ -11,7 +11,7 @@
import static org.mockito.internal.util.StringJoiner.join;
public class LoggingListener implements FindingsListener {
- private boolean warnAboutUnstubbed;
+ private final boolean warnAboutUnstubbed;
private final MockitoLogger logger;
public LoggingListener(boolean warnAboutUnstubbed, MockitoLogger logger) {
diff --git a/src/org/mockito/internal/debugging/MockitoDebuggerImpl.java b/src/org/mockito/internal/debugging/MockitoDebuggerImpl.java
index 06dcf56..2e82abb 100644
--- a/src/org/mockito/internal/debugging/MockitoDebuggerImpl.java
+++ b/src/org/mockito/internal/debugging/MockitoDebuggerImpl.java
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.debugging;
import org.mockito.MockitoDebugger;
@@ -15,8 +15,8 @@
public class MockitoDebuggerImpl implements MockitoDebugger {
- private AllInvocationsFinder allInvocationsFinder = new AllInvocationsFinder();
- private UnusedStubsFinder unusedStubsFinder = new UnusedStubsFinder();
+ private final AllInvocationsFinder allInvocationsFinder = new AllInvocationsFinder();
+ private final UnusedStubsFinder unusedStubsFinder = new UnusedStubsFinder();
public String printInvocations(Object ... mocks) {
String out = "";
diff --git a/src/org/mockito/internal/debugging/WarningsPrinterImpl.java b/src/org/mockito/internal/debugging/WarningsPrinterImpl.java
index ab4c364..2e6a75a 100644
--- a/src/org/mockito/internal/debugging/WarningsPrinterImpl.java
+++ b/src/org/mockito/internal/debugging/WarningsPrinterImpl.java
@@ -1,20 +1,20 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.debugging;
-import java.util.List;
-
import org.mockito.internal.invocation.InvocationMatcher;
import org.mockito.internal.util.MockitoLogger;
import org.mockito.internal.util.SimpleMockitoLogger;
import org.mockito.invocation.Invocation;
+import java.util.List;
+
public class WarningsPrinterImpl {
private final boolean warnAboutUnstubbed;
- private WarningsFinder finder;
+ private final WarningsFinder finder;
public WarningsPrinterImpl(List<Invocation> unusedStubs, List<InvocationMatcher> unstubbedInvocations) {
this(unusedStubs, unstubbedInvocations, false);
diff --git a/src/org/mockito/internal/exceptions/MockitoLimitations.java b/src/org/mockito/internal/exceptions/MockitoLimitations.java
new file mode 100644
index 0000000..bc6d9ba
--- /dev/null
+++ b/src/org/mockito/internal/exceptions/MockitoLimitations.java
@@ -0,0 +1,7 @@
+package org.mockito.internal.exceptions;
+
+public class MockitoLimitations {
+
+ public final static String NON_PUBLIC_PARENT = "Mocking methods declared on non-public parent classes is not supported.";
+
+}
diff --git a/src/org/mockito/internal/exceptions/stacktrace/ConditionalStackTraceFilter.java b/src/org/mockito/internal/exceptions/stacktrace/ConditionalStackTraceFilter.java
index b3af5a7..1996e40 100644
--- a/src/org/mockito/internal/exceptions/stacktrace/ConditionalStackTraceFilter.java
+++ b/src/org/mockito/internal/exceptions/stacktrace/ConditionalStackTraceFilter.java
@@ -11,10 +11,10 @@
import java.io.Serializable;
public class ConditionalStackTraceFilter implements Serializable {
- static final long serialVersionUID = -8085849703510292641L;
+ private static final long serialVersionUID = -8085849703510292641L;
- private IMockitoConfiguration config = new GlobalConfiguration();
- private StackTraceFilter filter = new StackTraceFilter();
+ private final IMockitoConfiguration config = new GlobalConfiguration();
+ private final StackTraceFilter filter = new StackTraceFilter();
public void filter(Throwable throwable) {
if (!config.cleansStackTrace()) {
diff --git a/src/org/mockito/internal/exceptions/stacktrace/StackTraceFilter.java b/src/org/mockito/internal/exceptions/stacktrace/StackTraceFilter.java
index a3e9d03..cd462dc 100644
--- a/src/org/mockito/internal/exceptions/stacktrace/StackTraceFilter.java
+++ b/src/org/mockito/internal/exceptions/stacktrace/StackTraceFilter.java
@@ -6,7 +6,7 @@
package org.mockito.internal.exceptions.stacktrace;
import org.mockito.exceptions.stacktrace.StackTraceCleaner;
-import org.mockito.internal.configuration.ClassPathLoader;
+import org.mockito.internal.configuration.plugins.Plugins;
import java.io.Serializable;
import java.util.ArrayList;
@@ -18,8 +18,8 @@
static final long serialVersionUID = -5499819791513105700L;
- private static StackTraceCleaner cleaner =
- ClassPathLoader.getStackTraceCleanerProvider().getStackTraceCleaner(new DefaultStackTraceCleaner());
+ private static final StackTraceCleaner CLEANER =
+ Plugins.getStackTraceCleanerProvider().getStackTraceCleaner(new DefaultStackTraceCleaner());
/**
* Example how the filter works (+/- means good/bad):
@@ -33,7 +33,7 @@
int lastBad = -1;
int firstBad = -1;
for (int i = 0; i < unfilteredStackTrace.size(); i++) {
- if (!cleaner.isOut(unfilteredStackTrace.get(i))) {
+ if (!CLEANER.isOut(unfilteredStackTrace.get(i))) {
continue;
}
lastBad = i;
diff --git a/src/org/mockito/internal/handler/InvocationNotifierHandler.java b/src/org/mockito/internal/handler/InvocationNotifierHandler.java
index 71030c4..3876812 100644
--- a/src/org/mockito/internal/handler/InvocationNotifierHandler.java
+++ b/src/org/mockito/internal/handler/InvocationNotifierHandler.java
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.handler;
import org.mockito.exceptions.Reporter;
@@ -25,8 +25,8 @@
*/
class InvocationNotifierHandler<T> implements MockHandler, InternalMockHandler<T> {
- private List<InvocationListener> invocationListeners;
- private InternalMockHandler<T> mockHandler;
+ private final List<InvocationListener> invocationListeners;
+ private final InternalMockHandler<T> mockHandler;
public InvocationNotifierHandler(InternalMockHandler<T> mockHandler, MockCreationSettings settings) {
this.mockHandler = mockHandler;
diff --git a/src/org/mockito/internal/invocation/AbstractAwareMethod.java b/src/org/mockito/internal/invocation/AbstractAwareMethod.java
new file mode 100644
index 0000000..2b36073
--- /dev/null
+++ b/src/org/mockito/internal/invocation/AbstractAwareMethod.java
@@ -0,0 +1,10 @@
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
+
+package org.mockito.internal.invocation;
+
+public interface AbstractAwareMethod {
+ boolean isAbstract();
+}
diff --git a/src/org/mockito/internal/invocation/ArgumentsComparator.java b/src/org/mockito/internal/invocation/ArgumentsComparator.java
index 416a40f..1f16c92 100644
--- a/src/org/mockito/internal/invocation/ArgumentsComparator.java
+++ b/src/org/mockito/internal/invocation/ArgumentsComparator.java
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.invocation;
import org.hamcrest.Matcher;
diff --git a/src/org/mockito/internal/invocation/InvocationImpl.java b/src/org/mockito/internal/invocation/InvocationImpl.java
index 6b6f8c8..19193fa 100644
--- a/src/org/mockito/internal/invocation/InvocationImpl.java
+++ b/src/org/mockito/internal/invocation/InvocationImpl.java
@@ -62,6 +62,10 @@
return arguments;
}
+ public <T> T getArgumentAt(int index, Class<T> clazz) {
+ return (T) arguments[index];
+ }
+
public boolean isVerified() {
return verified || isIgnoredForVerification;
}
@@ -102,8 +106,8 @@
}
public Object callRealMethod() throws Throwable {
- if (this.getMethod().getDeclaringClass().isInterface()) {
- new Reporter().cannotCallRealMethodOnInterface();
+ if (method.isAbstract()) {
+ new Reporter().cannotCallAbstractRealMethod();
}
return realMethod.invoke(mock, rawArguments);
}
diff --git a/src/org/mockito/internal/invocation/InvocationMatcher.java b/src/org/mockito/internal/invocation/InvocationMatcher.java
index 86e83ca..98d29b3 100644
--- a/src/org/mockito/internal/invocation/InvocationMatcher.java
+++ b/src/org/mockito/internal/invocation/InvocationMatcher.java
@@ -5,12 +5,6 @@
package org.mockito.internal.invocation;
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-
import org.hamcrest.Matcher;
import org.mockito.internal.matchers.CapturesArguments;
import org.mockito.internal.matchers.MatcherDecorator;
@@ -20,6 +14,13 @@
import org.mockito.invocation.Invocation;
import org.mockito.invocation.Location;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
@SuppressWarnings("unchecked")
public class InvocationMatcher implements DescribedInvocation, CapturesArgumensFromInvocation, Serializable {
@@ -120,11 +121,17 @@
public void captureArgumentsFrom(Invocation invocation) {
for (int position = 0; position < matchers.size(); position++) {
Matcher m = matchers.get(position);
- if (m instanceof CapturesArguments && invocation.getArguments().length > position) {
+ if (m instanceof CapturesArguments && invocation.getRawArguments().length > position) {
+ //TODO SF - this whole lot can be moved captureFrom implementation
if(isVariableArgument(invocation, position) && isVarargMatcher(m)) {
- ((CapturesArguments) m).captureFrom(invocation.getRawArguments()[position]);
+ Object array = invocation.getRawArguments()[position];
+ for (int i = 0; i < Array.getLength(array); i++) {
+ ((CapturesArguments) m).captureFrom(Array.get(array, i));
+ }
+ //since we've captured all varargs already, it does not make sense to process other matchers.
+ return;
} else {
- ((CapturesArguments) m).captureFrom(invocation.getArguments()[position]);
+ ((CapturesArguments) m).captureFrom(invocation.getRawArguments()[position]);
}
}
}
diff --git a/src/org/mockito/internal/invocation/InvocationsFinder.java b/src/org/mockito/internal/invocation/InvocationsFinder.java
index b88162b..3e30cb0 100644
--- a/src/org/mockito/internal/invocation/InvocationsFinder.java
+++ b/src/org/mockito/internal/invocation/InvocationsFinder.java
@@ -134,7 +134,7 @@
return unverified;
}
- private class RemoveNotMatching implements Filter<Invocation> {
+ private static class RemoveNotMatching implements Filter<Invocation> {
private final InvocationMatcher wanted;
private RemoveNotMatching(InvocationMatcher wanted) {
@@ -146,7 +146,7 @@
}
}
- private class RemoveUnverifiedInOrder implements Filter<Invocation> {
+ private static class RemoveUnverifiedInOrder implements Filter<Invocation> {
private final InOrderContext orderingContext;
public RemoveUnverifiedInOrder(InOrderContext orderingContext) {
diff --git a/src/org/mockito/internal/invocation/MockitoMethod.java b/src/org/mockito/internal/invocation/MockitoMethod.java
index 09ea414..1048b55 100644
--- a/src/org/mockito/internal/invocation/MockitoMethod.java
+++ b/src/org/mockito/internal/invocation/MockitoMethod.java
@@ -1,12 +1,12 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.invocation;
import java.lang.reflect.Method;
-public interface MockitoMethod {
+public interface MockitoMethod extends AbstractAwareMethod {
public String getName();
diff --git a/src/org/mockito/internal/invocation/SerializableMethod.java b/src/org/mockito/internal/invocation/SerializableMethod.java
index 652bf6b..2bb534b 100644
--- a/src/org/mockito/internal/invocation/SerializableMethod.java
+++ b/src/org/mockito/internal/invocation/SerializableMethod.java
@@ -1,25 +1,27 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.invocation;
+import org.mockito.exceptions.base.MockitoException;
+
import java.io.Serializable;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
import java.util.Arrays;
-import org.mockito.exceptions.base.MockitoException;
-
public class SerializableMethod implements Serializable, MockitoMethod {
private static final long serialVersionUID = 6005610965006048445L;
-
- private Class<?> declaringClass;
- private String methodName;
- private Class<?>[] parameterTypes;
- private Class<?> returnType;
- private Class<?>[] exceptionTypes;
- private boolean isVarArgs;
+
+ private final Class<?> declaringClass;
+ private final String methodName;
+ private final Class<?>[] parameterTypes;
+ private final Class<?> returnType;
+ private final Class<?>[] exceptionTypes;
+ private final boolean isVarArgs;
+ private final boolean isAbstract;
public SerializableMethod(Method method) {
declaringClass = method.getDeclaringClass();
@@ -28,6 +30,7 @@
returnType = method.getReturnType();
exceptionTypes = method.getExceptionTypes();
isVarArgs = method.isVarArgs();
+ isAbstract = (method.getModifiers() & Modifier.ABSTRACT) != 0;
}
public String getName() {
@@ -48,7 +51,11 @@
public boolean isVarArgs() {
return isVarArgs;
- }
+ }
+
+ public boolean isAbstract() {
+ return isAbstract;
+ }
public Method getJavaMethod() {
try {
@@ -64,7 +71,7 @@
"Please report this as a defect with an example of how to reproduce it.", declaringClass, methodName);
throw new MockitoException(message, e);
}
- }
+ }
@Override
public int hashCode() {
diff --git a/src/org/mockito/internal/invocation/StubInfoImpl.java b/src/org/mockito/internal/invocation/StubInfoImpl.java
index cdd245e..9e63afe 100644
--- a/src/org/mockito/internal/invocation/StubInfoImpl.java
+++ b/src/org/mockito/internal/invocation/StubInfoImpl.java
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.invocation;
import org.mockito.invocation.DescribedInvocation;
@@ -12,7 +12,7 @@
public class StubInfoImpl implements StubInfo, Serializable {
private static final long serialVersionUID = 2125827349332068867L;
- private DescribedInvocation stubbedAt;
+ private final DescribedInvocation stubbedAt;
public StubInfoImpl(DescribedInvocation stubbedAt) {
this.stubbedAt = stubbedAt;
diff --git a/src/org/mockito/internal/invocation/finder/AllInvocationsFinder.java b/src/org/mockito/internal/invocation/finder/AllInvocationsFinder.java
index bcc9fb3..cfe3346 100644
--- a/src/org/mockito/internal/invocation/finder/AllInvocationsFinder.java
+++ b/src/org/mockito/internal/invocation/finder/AllInvocationsFinder.java
@@ -30,7 +30,7 @@
return new LinkedList<Invocation>(invocationsInOrder);
}
- private final class SequenceNumberComparator implements Comparator<Invocation> {
+ private static final class SequenceNumberComparator implements Comparator<Invocation> {
public int compare(Invocation o1, Invocation o2) {
return Integer.valueOf(o1.getSequenceNumber()).compareTo(o2.getSequenceNumber());
}
diff --git a/src/org/mockito/internal/invocation/finder/VerifiableInvocationsFinder.java b/src/org/mockito/internal/invocation/finder/VerifiableInvocationsFinder.java
index ae25481..2d4a71e 100644
--- a/src/org/mockito/internal/invocation/finder/VerifiableInvocationsFinder.java
+++ b/src/org/mockito/internal/invocation/finder/VerifiableInvocationsFinder.java
@@ -6,6 +6,7 @@
package org.mockito.internal.invocation.finder;
import org.mockito.internal.util.collections.ListUtil;
+import org.mockito.internal.util.collections.ListUtil.Filter;
import org.mockito.invocation.Invocation;
import java.util.List;
@@ -20,9 +21,9 @@
return ListUtil.filter(invocations, new RemoveIgnoredForVerification());
}
- static class RemoveIgnoredForVerification implements ListUtil.Filter<Invocation>{
- public boolean isOut(Invocation i) {
- return i.isIgnoredForVerification();
+ private static class RemoveIgnoredForVerification implements Filter<Invocation>{
+ public boolean isOut(Invocation invocation) {
+ return invocation.isIgnoredForVerification();
}
}
}
diff --git a/src/org/mockito/internal/invocation/realmethod/FilteredCGLIBProxyRealMethod.java b/src/org/mockito/internal/invocation/realmethod/CleanTraceRealMethod.java
similarity index 60%
rename from src/org/mockito/internal/invocation/realmethod/FilteredCGLIBProxyRealMethod.java
rename to src/org/mockito/internal/invocation/realmethod/CleanTraceRealMethod.java
index 39c3b86..b7964e8 100644
--- a/src/org/mockito/internal/invocation/realmethod/FilteredCGLIBProxyRealMethod.java
+++ b/src/org/mockito/internal/invocation/realmethod/CleanTraceRealMethod.java
@@ -1,37 +1,36 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
-package org.mockito.internal.invocation.realmethod;
-
-import org.mockito.internal.creation.MockitoMethodProxy;
-import org.mockito.internal.exceptions.stacktrace.ConditionalStackTraceFilter;
-
-import java.io.Serializable;
-
-public class FilteredCGLIBProxyRealMethod implements RealMethod, HasCGLIBMethodProxy, Serializable {
-
- private static final long serialVersionUID = 3596550785818938496L;
- private final RealMethod realMethod;
-
- public FilteredCGLIBProxyRealMethod(MockitoMethodProxy methodProxy) {
- this(new CGLIBProxyRealMethod(methodProxy));
- }
-
- public FilteredCGLIBProxyRealMethod(RealMethod realMethod) {
- this.realMethod = realMethod;
- }
-
- public Object invoke(Object target, Object[] arguments) throws Throwable {
- try {
- return realMethod.invoke(target, arguments);
- } catch (Throwable t) {
- new ConditionalStackTraceFilter().filter(t);
- throw t;
- }
- }
-
- public MockitoMethodProxy getMethodProxy() {
- return ((HasCGLIBMethodProxy) realMethod).getMethodProxy();
- }
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
+package org.mockito.internal.invocation.realmethod;
+
+import org.mockito.internal.creation.util.MockitoMethodProxy;
+import org.mockito.internal.exceptions.stacktrace.ConditionalStackTraceFilter;
+
+import java.io.Serializable;
+
+/**
+ * Provides stack trace filtering on exception.
+ */
+public class CleanTraceRealMethod implements RealMethod, Serializable {
+
+ private static final long serialVersionUID = 3596550785818938496L;
+ private final RealMethod realMethod;
+
+ public CleanTraceRealMethod(MockitoMethodProxy methodProxy) {
+ this(new DefaultRealMethod(methodProxy));
+ }
+
+ public CleanTraceRealMethod(RealMethod realMethod) {
+ this.realMethod = realMethod;
+ }
+
+ public Object invoke(Object target, Object[] arguments) throws Throwable {
+ try {
+ return realMethod.invoke(target, arguments);
+ } catch (Throwable t) {
+ new ConditionalStackTraceFilter().filter(t);
+ throw t;
+ }
+ }
}
\ No newline at end of file
diff --git a/src/org/mockito/internal/invocation/realmethod/CGLIBProxyRealMethod.java b/src/org/mockito/internal/invocation/realmethod/DefaultRealMethod.java
similarity index 63%
rename from src/org/mockito/internal/invocation/realmethod/CGLIBProxyRealMethod.java
rename to src/org/mockito/internal/invocation/realmethod/DefaultRealMethod.java
index 140ae8e..49ad30a 100644
--- a/src/org/mockito/internal/invocation/realmethod/CGLIBProxyRealMethod.java
+++ b/src/org/mockito/internal/invocation/realmethod/DefaultRealMethod.java
@@ -2,27 +2,22 @@
* Copyright (c) 2007 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
-package org.mockito.internal.invocation.realmethod;
-
-import java.io.Serializable;
-
-import org.mockito.internal.creation.MockitoMethodProxy;
-
-
-public class CGLIBProxyRealMethod implements RealMethod, HasCGLIBMethodProxy, Serializable {
-
- private static final long serialVersionUID = -4596470901191501582L;
- private final MockitoMethodProxy methodProxy;
-
- public CGLIBProxyRealMethod(MockitoMethodProxy methodProxy) {
- this.methodProxy = methodProxy;
- }
-
- public Object invoke(Object target, Object[] arguments) throws Throwable {
- return methodProxy.invokeSuper(target, arguments);
- }
-
- public MockitoMethodProxy getMethodProxy() {
- return methodProxy;
- }
-}
+package org.mockito.internal.invocation.realmethod;
+
+import org.mockito.internal.creation.util.MockitoMethodProxy;
+
+import java.io.Serializable;
+
+public class DefaultRealMethod implements RealMethod, Serializable {
+
+ private static final long serialVersionUID = -4596470901191501582L;
+ private final MockitoMethodProxy methodProxy;
+
+ public DefaultRealMethod(MockitoMethodProxy methodProxy) {
+ this.methodProxy = methodProxy;
+ }
+
+ public Object invoke(Object target, Object[] arguments) throws Throwable {
+ return methodProxy.invokeSuper(target, arguments);
+ }
+}
diff --git a/src/org/mockito/internal/invocation/realmethod/HasCGLIBMethodProxy.java b/src/org/mockito/internal/invocation/realmethod/HasCGLIBMethodProxy.java
deleted file mode 100644
index 299bc16..0000000
--- a/src/org/mockito/internal/invocation/realmethod/HasCGLIBMethodProxy.java
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
-package org.mockito.internal.invocation.realmethod;
-
-import java.io.Serializable;
-
-import org.mockito.internal.creation.MockitoMethodProxy;
-
-public interface HasCGLIBMethodProxy extends Serializable {
-
- MockitoMethodProxy getMethodProxy();
-}
diff --git a/src/org/mockito/internal/invocation/realmethod/RealMethod.java b/src/org/mockito/internal/invocation/realmethod/RealMethod.java
index 1812c4b..3f2e785 100644
--- a/src/org/mockito/internal/invocation/realmethod/RealMethod.java
+++ b/src/org/mockito/internal/invocation/realmethod/RealMethod.java
@@ -1,10 +1,9 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.invocation.realmethod;
-
public interface RealMethod {
Object invoke(Object target, Object[] arguments) throws Throwable;
diff --git a/src/org/mockito/internal/junit/FriendlyExceptionMaker.java b/src/org/mockito/internal/junit/FriendlyExceptionMaker.java
new file mode 100644
index 0000000..f454fd2
--- /dev/null
+++ b/src/org/mockito/internal/junit/FriendlyExceptionMaker.java
@@ -0,0 +1,32 @@
+package org.mockito.internal.junit;
+
+import org.mockito.exceptions.verification.ArgumentsAreDifferent;
+
+/**
+ * If JUnit is used, we can use an exception that extends from ComparisonFailure
+ * and hence provide a better IDE support as the comparison result is comparable
+ */
+class FriendlyExceptionMaker {
+
+ private final JUnitDetecter detecter;
+
+ FriendlyExceptionMaker(JUnitDetecter detecter) {
+ this.detecter = detecter;
+ }
+
+ //TODO SF this can be now unit tested
+ public AssertionError createArgumentsAreDifferentException(String message, String wanted, String actual) {
+ if (!detecter.hasJUnit()) {
+ return new ArgumentsAreDifferent(message);
+ }
+
+ try {
+ Class<?> clazz = Class.forName("org.mockito.exceptions.verification.junit.ArgumentsAreDifferent");
+ AssertionError throwable = (AssertionError) clazz.getConstructors()[0].newInstance(message, wanted, actual);
+ return throwable;
+ } catch (Throwable t) {
+// throw the default exception in case of problems
+ return new ArgumentsAreDifferent(message);
+ }
+ }
+}
diff --git a/src/org/mockito/internal/junit/JUnitDetecter.java b/src/org/mockito/internal/junit/JUnitDetecter.java
new file mode 100644
index 0000000..3ccc7f0
--- /dev/null
+++ b/src/org/mockito/internal/junit/JUnitDetecter.java
@@ -0,0 +1,19 @@
+package org.mockito.internal.junit;
+
+class JUnitDetecter {
+
+ private boolean hasJUnit;
+
+ JUnitDetecter() {
+ try {
+ Class.forName("junit.framework.ComparisonFailure");
+ hasJUnit = true;
+ } catch (Throwable t) {
+ hasJUnit = false;
+ }
+ }
+
+ public boolean hasJUnit() {
+ return hasJUnit;
+ }
+}
diff --git a/src/org/mockito/internal/junit/JUnitRule.java b/src/org/mockito/internal/junit/JUnitRule.java
new file mode 100644
index 0000000..a5c0238
--- /dev/null
+++ b/src/org/mockito/internal/junit/JUnitRule.java
@@ -0,0 +1,21 @@
+package org.mockito.internal.junit;
+
+import org.junit.runners.model.Statement;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Internal implementation.
+ */
+public class JUnitRule {
+ public Statement apply(final Statement base, final Object target) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ MockitoAnnotations.initMocks(target);
+ base.evaluate();
+ Mockito.validateMockitoUsage();
+ }
+ };
+ }
+}
diff --git a/src/org/mockito/internal/junit/JUnitTool.java b/src/org/mockito/internal/junit/JUnitTool.java
index 5d9c53b..0d72f96 100644
--- a/src/org/mockito/internal/junit/JUnitTool.java
+++ b/src/org/mockito/internal/junit/JUnitTool.java
@@ -1,36 +1,18 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.junit;
-import org.mockito.exceptions.verification.ArgumentsAreDifferent;
-
public class JUnitTool {
- private static boolean hasJUnit;
+ private static JUnitDetecter detecter = new JUnitDetecter();
- static {
- try {
- Class.forName("junit.framework.ComparisonFailure");
- hasJUnit = true;
- } catch (Throwable t) {
- hasJUnit = false;
- }
- }
-
public static boolean hasJUnit() {
- return hasJUnit;
+ return detecter.hasJUnit();
}
public static AssertionError createArgumentsAreDifferentException(String message, String wanted, String actual) {
- try {
- Class<?> clazz = Class.forName("org.mockito.exceptions.verification.junit.ArgumentsAreDifferent");
- AssertionError throwable = (AssertionError) clazz.getConstructors()[0].newInstance(message, wanted, actual);
- return throwable;
- } catch (Throwable t) {
-// throw the default exception in case of problems
- return new ArgumentsAreDifferent(message);
- }
+ return new FriendlyExceptionMaker(detecter).createArgumentsAreDifferentException(message, wanted, actual);
}
}
\ No newline at end of file
diff --git a/src/org/mockito/internal/listeners/CollectCreatedMocks.java b/src/org/mockito/internal/listeners/CollectCreatedMocks.java
index 6592fd8..922ee23 100644
--- a/src/org/mockito/internal/listeners/CollectCreatedMocks.java
+++ b/src/org/mockito/internal/listeners/CollectCreatedMocks.java
@@ -1,17 +1,15 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.listeners;
-import org.mockito.MockSettings;
-
import java.util.List;
@SuppressWarnings("unchecked")
public class CollectCreatedMocks implements MockingStartedListener {
- private List toBeFilled;
+ private final List toBeFilled;
public CollectCreatedMocks(List toBeFilled) {
this.toBeFilled = toBeFilled;
diff --git a/src/org/mockito/internal/listeners/NotifiedMethodInvocationReport.java b/src/org/mockito/internal/listeners/NotifiedMethodInvocationReport.java
index f1eca81..d73450a 100644
--- a/src/org/mockito/internal/listeners/NotifiedMethodInvocationReport.java
+++ b/src/org/mockito/internal/listeners/NotifiedMethodInvocationReport.java
@@ -1,20 +1,22 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.listeners;
import org.mockito.invocation.DescribedInvocation;
import org.mockito.invocation.Invocation;
import org.mockito.listeners.MethodInvocationReport;
+import static org.mockito.internal.matchers.Equality.areEqual;
+
/**
* Report on a method call
*/
public class NotifiedMethodInvocationReport implements MethodInvocationReport {
private final Invocation invocation;
- private Object returnedValue;
- private Throwable throwable;
+ private final Object returnedValue;
+ private final Throwable throwable;
/**
@@ -27,6 +29,7 @@
public NotifiedMethodInvocationReport(Invocation invocation, Object returnedValue) {
this.invocation = invocation;
this.returnedValue = returnedValue;
+ this.throwable = null;
}
/**
@@ -38,6 +41,7 @@
*/
public NotifiedMethodInvocationReport(Invocation invocation, Throwable throwable) {
this.invocation = invocation;
+ this.returnedValue = null;
this.throwable = throwable;
}
@@ -68,12 +72,9 @@
NotifiedMethodInvocationReport that = (NotifiedMethodInvocationReport) o;
- if (invocation != null ? !invocation.equals(that.invocation) : that.invocation != null) return false;
- if (returnedValue != null ? !returnedValue.equals(that.returnedValue) : that.returnedValue != null)
- return false;
- if (throwable != null ? !throwable.equals(that.throwable) : that.throwable != null) return false;
-
- return true;
+ return areEqual(invocation, that.invocation) &&
+ areEqual(returnedValue, that.returnedValue) &&
+ areEqual(throwable, that.throwable);
}
public int hashCode() {
diff --git a/src/org/mockito/internal/matchers/CapturingMatcher.java b/src/org/mockito/internal/matchers/CapturingMatcher.java
index 3503387..80759fa 100644
--- a/src/org/mockito/internal/matchers/CapturingMatcher.java
+++ b/src/org/mockito/internal/matchers/CapturingMatcher.java
@@ -1,22 +1,22 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.matchers;
-import java.io.Serializable;
-import java.util.LinkedList;
-import java.util.List;
-
import org.hamcrest.Description;
import org.mockito.ArgumentMatcher;
import org.mockito.exceptions.Reporter;
+import java.io.Serializable;
+import java.util.LinkedList;
+import java.util.List;
+
@SuppressWarnings("unchecked")
-public class CapturingMatcher<T> extends ArgumentMatcher<T> implements CapturesArguments, Serializable {
+public class CapturingMatcher<T> extends ArgumentMatcher<T> implements CapturesArguments, VarargMatcher, Serializable {
private static final long serialVersionUID = 4274067078639307295L;
- private LinkedList<Object> arguments = new LinkedList<Object>();
+ private final LinkedList<Object> arguments = new LinkedList<Object>();
/* (non-Javadoc)
* @see org.mockito.ArgumentMatcher#matches(java.lang.Object)
diff --git a/src/org/mockito/internal/matchers/Equality.java b/src/org/mockito/internal/matchers/Equality.java
index 43e11fc..0791441 100644
--- a/src/org/mockito/internal/matchers/Equality.java
+++ b/src/org/mockito/internal/matchers/Equality.java
@@ -10,7 +10,9 @@
public class Equality {
public static boolean areEqual(Object o1, Object o2) {
- if (o1 == null || o2 == null) {
+ if (o1 == o2 ) {
+ return true;
+ } else if (o1 == null || o2 == null) {
return o1 == null && o2 == null;
} else if (isArray(o1)) {
return isArray(o2) && areArraysEqual(o1, o2);
diff --git a/src/org/mockito/internal/matchers/Equals.java b/src/org/mockito/internal/matchers/Equals.java
index 4631de6..b712622 100644
--- a/src/org/mockito/internal/matchers/Equals.java
+++ b/src/org/mockito/internal/matchers/Equals.java
@@ -29,10 +29,7 @@
}
public String describe(Object object) {
- String text = quoting();
- text+="" + object;
- text+= quoting();
- return text;
+ return quoting() + object + quoting();
}
private String quoting() {
diff --git a/src/org/mockito/internal/matchers/EqualsWithDelta.java b/src/org/mockito/internal/matchers/EqualsWithDelta.java
index 6e35038..7e99b08 100644
--- a/src/org/mockito/internal/matchers/EqualsWithDelta.java
+++ b/src/org/mockito/internal/matchers/EqualsWithDelta.java
@@ -29,7 +29,7 @@
return false;
}
- if (wanted == null && actual == null) {
+ if (wanted == actual) {
return true;
}
diff --git a/src/org/mockito/internal/matchers/LocalizedMatcher.java b/src/org/mockito/internal/matchers/LocalizedMatcher.java
index 4021ce0..b19cdf5 100644
--- a/src/org/mockito/internal/matchers/LocalizedMatcher.java
+++ b/src/org/mockito/internal/matchers/LocalizedMatcher.java
@@ -1,21 +1,23 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.matchers;
-import java.io.Serializable;
-
-import org.hamcrest.*;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.SelfDescribing;
import org.mockito.internal.debugging.LocationImpl;
import org.mockito.invocation.Location;
+import java.io.Serializable;
+
@SuppressWarnings("unchecked")
public class LocalizedMatcher implements Matcher, ContainsExtraTypeInformation, CapturesArguments, MatcherDecorator, Serializable {
private static final long serialVersionUID = 6748641229659825725L;
private final Matcher actualMatcher;
- private Location location;
+ private final Location location;
public LocalizedMatcher(Matcher actualMatcher) {
this.actualMatcher = actualMatcher;
diff --git a/src/org/mockito/internal/matchers/VarargCapturingMatcher.java b/src/org/mockito/internal/matchers/VarargCapturingMatcher.java
index 103378b..cc978e0 100644
--- a/src/org/mockito/internal/matchers/VarargCapturingMatcher.java
+++ b/src/org/mockito/internal/matchers/VarargCapturingMatcher.java
@@ -15,7 +15,7 @@
@SuppressWarnings("unchecked")
public class VarargCapturingMatcher<T> extends ArgumentMatcher<T> implements CapturesArguments, VarargMatcher, Serializable {
private static final long serialVersionUID = 4057053345838026645L;
- private LinkedList<List<T>> arguments = new LinkedList<List<T>>();
+ private final LinkedList<List<T>> arguments = new LinkedList<List<T>>();
public boolean matches(Object argument) {
return true;
diff --git a/src/org/mockito/internal/matchers/apachecommons/EqualsBuilder.java b/src/org/mockito/internal/matchers/apachecommons/EqualsBuilder.java
index 97ea911..76704f9 100644
--- a/src/org/mockito/internal/matchers/apachecommons/EqualsBuilder.java
+++ b/src/org/mockito/internal/matchers/apachecommons/EqualsBuilder.java
@@ -315,10 +315,7 @@
* @since 2.0
*/
public EqualsBuilder appendSuper(boolean superEquals) {
- if (isEquals == false) {
- return this;
- }
- isEquals = superEquals;
+ isEquals &= superEquals;
return this;
}
@@ -333,7 +330,7 @@
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(Object lhs, Object rhs) {
- if (isEquals == false) {
+ if (!isEquals) {
return this;
}
if (lhs == rhs) {
@@ -392,10 +389,7 @@
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(long lhs, long rhs) {
- if (isEquals == false) {
- return this;
- }
- isEquals = (lhs == rhs);
+ isEquals &= (lhs == rhs);
return this;
}
@@ -407,10 +401,7 @@
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(int lhs, int rhs) {
- if (isEquals == false) {
- return this;
- }
- isEquals = (lhs == rhs);
+ isEquals &= (lhs == rhs);
return this;
}
@@ -422,10 +413,7 @@
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(short lhs, short rhs) {
- if (isEquals == false) {
- return this;
- }
- isEquals = (lhs == rhs);
+ isEquals &= (lhs == rhs);
return this;
}
@@ -437,10 +425,7 @@
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(char lhs, char rhs) {
- if (isEquals == false) {
- return this;
- }
- isEquals = (lhs == rhs);
+ isEquals &= (lhs == rhs);
return this;
}
@@ -452,10 +437,7 @@
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(byte lhs, byte rhs) {
- if (isEquals == false) {
- return this;
- }
- isEquals = (lhs == rhs);
+ isEquals &= (lhs == rhs);
return this;
}
@@ -473,7 +455,7 @@
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(double lhs, double rhs) {
- if (isEquals == false) {
+ if (!isEquals) {
return this;
}
return append(Double.doubleToLongBits(lhs), Double.doubleToLongBits(rhs));
@@ -493,7 +475,7 @@
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(float lhs, float rhs) {
- if (isEquals == false) {
+ if (!isEquals) {
return this;
}
return append(Float.floatToIntBits(lhs), Float.floatToIntBits(rhs));
@@ -507,10 +489,7 @@
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(boolean lhs, boolean rhs) {
- if (isEquals == false) {
- return this;
- }
- isEquals = (lhs == rhs);
+ isEquals &= (lhs == rhs);
return this;
}
@@ -525,7 +504,7 @@
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(Object[] lhs, Object[] rhs) {
- if (isEquals == false) {
+ if (!isEquals) {
return this;
}
if (lhs == rhs) {
@@ -556,7 +535,7 @@
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(long[] lhs, long[] rhs) {
- if (isEquals == false) {
+ if (!isEquals) {
return this;
}
if (lhs == rhs) {
@@ -587,7 +566,7 @@
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(int[] lhs, int[] rhs) {
- if (isEquals == false) {
+ if (!isEquals) {
return this;
}
if (lhs == rhs) {
@@ -618,7 +597,7 @@
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(short[] lhs, short[] rhs) {
- if (isEquals == false) {
+ if (!isEquals) {
return this;
}
if (lhs == rhs) {
@@ -649,7 +628,7 @@
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(char[] lhs, char[] rhs) {
- if (isEquals == false) {
+ if (!isEquals) {
return this;
}
if (lhs == rhs) {
@@ -680,7 +659,7 @@
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(byte[] lhs, byte[] rhs) {
- if (isEquals == false) {
+ if (!isEquals) {
return this;
}
if (lhs == rhs) {
@@ -711,7 +690,7 @@
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(double[] lhs, double[] rhs) {
- if (isEquals == false) {
+ if (!isEquals) {
return this;
}
if (lhs == rhs) {
@@ -742,7 +721,7 @@
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(float[] lhs, float[] rhs) {
- if (isEquals == false) {
+ if (!isEquals) {
return this;
}
if (lhs == rhs) {
@@ -773,7 +752,7 @@
* @return EqualsBuilder - used to chain calls.
*/
public EqualsBuilder append(boolean[] lhs, boolean[] rhs) {
- if (isEquals == false) {
+ if (!isEquals) {
return this;
}
if (lhs == rhs) {
diff --git a/src/org/mockito/internal/progress/ArgumentMatcherStorageImpl.java b/src/org/mockito/internal/progress/ArgumentMatcherStorageImpl.java
index 6ab59d6..c8d68b6 100644
--- a/src/org/mockito/internal/progress/ArgumentMatcherStorageImpl.java
+++ b/src/org/mockito/internal/progress/ArgumentMatcherStorageImpl.java
@@ -23,7 +23,7 @@
public static final int TWO_SUB_MATCHERS = 2;
public static final int ONE_SUB_MATCHER = 1;
- private Stack<LocalizedMatcher> matcherStack = new Stack<LocalizedMatcher>();
+ private final Stack<LocalizedMatcher> matcherStack = new Stack<LocalizedMatcher>();
/* (non-Javadoc)
* @see org.mockito.internal.progress.ArgumentMatcherStorage#reportMatcher(org.hamcrest.Matcher)
diff --git a/src/org/mockito/internal/progress/MockingProgressImpl.java b/src/org/mockito/internal/progress/MockingProgressImpl.java
index f21b50d..e9235d9 100644
--- a/src/org/mockito/internal/progress/MockingProgressImpl.java
+++ b/src/org/mockito/internal/progress/MockingProgressImpl.java
@@ -5,7 +5,6 @@
package org.mockito.internal.progress;
-import org.mockito.MockSettings;
import org.mockito.exceptions.Reporter;
import org.mockito.internal.configuration.GlobalConfiguration;
import org.mockito.internal.debugging.Localized;
@@ -111,7 +110,7 @@
}
public void mockingStarted(Object mock, Class classToMock) {
- if (listener != null && listener instanceof MockingStartedListener) {
+ if (listener instanceof MockingStartedListener) {
((MockingStartedListener) listener).mockingStarted(mock, classToMock);
}
validateMostStuff();
diff --git a/src/org/mockito/internal/progress/ThreadSafeMockingProgress.java b/src/org/mockito/internal/progress/ThreadSafeMockingProgress.java
index a8a6dd3..669af6d 100644
--- a/src/org/mockito/internal/progress/ThreadSafeMockingProgress.java
+++ b/src/org/mockito/internal/progress/ThreadSafeMockingProgress.java
@@ -5,18 +5,17 @@
package org.mockito.internal.progress;
-import java.io.Serializable;
-
-import org.mockito.MockSettings;
import org.mockito.internal.listeners.MockingProgressListener;
import org.mockito.invocation.Invocation;
import org.mockito.verification.VerificationMode;
+import java.io.Serializable;
+
@SuppressWarnings("unchecked")
public class ThreadSafeMockingProgress implements MockingProgress, Serializable {
private static final long serialVersionUID = 6839454041642082618L;
- private static ThreadLocal<MockingProgress> mockingProgress = new ThreadLocal<MockingProgress>();
+ private static final ThreadLocal<MockingProgress> mockingProgress = new ThreadLocal<MockingProgress>();
static MockingProgress threadSafely() {
if (mockingProgress.get() == null) {
diff --git a/src/org/mockito/internal/runners/JUnit45AndHigherRunnerImpl.java b/src/org/mockito/internal/runners/JUnit45AndHigherRunnerImpl.java
index 700c659..d7c6ada 100644
--- a/src/org/mockito/internal/runners/JUnit45AndHigherRunnerImpl.java
+++ b/src/org/mockito/internal/runners/JUnit45AndHigherRunnerImpl.java
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.runners;
import org.junit.runner.Description;
@@ -17,7 +17,7 @@
public class JUnit45AndHigherRunnerImpl implements RunnerImpl {
- private BlockJUnit4ClassRunner runner;
+ private final BlockJUnit4ClassRunner runner;
public JUnit45AndHigherRunnerImpl(Class<?> klass) throws InitializationError {
runner = new BlockJUnit4ClassRunner(klass) {
diff --git a/src/org/mockito/internal/stubbing/BaseStubbing.java b/src/org/mockito/internal/stubbing/BaseStubbing.java
index 401cf9f..80270fa 100644
--- a/src/org/mockito/internal/stubbing/BaseStubbing.java
+++ b/src/org/mockito/internal/stubbing/BaseStubbing.java
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.stubbing;
import org.mockito.internal.stubbing.answers.CallsRealMethods;
@@ -12,6 +12,8 @@
import org.mockito.stubbing.OngoingStubbing;
public abstract class BaseStubbing<T> implements OngoingStubbing<T>, DeprecatedOngoingStubbing<T> {
+
+ //TODO why we need this method? The other thenReturn covers it.
public OngoingStubbing<T> thenReturn(T value) {
return thenAnswer(new Returns(value));
}
@@ -19,6 +21,7 @@
public OngoingStubbing<T> thenReturn(T value, T... values) {
OngoingStubbing<T> stubbing = thenReturn(value);
if (values == null) {
+ //TODO below does not seem right
return stubbing.thenReturn(null);
}
for (T v: values) {
diff --git a/src/org/mockito/internal/stubbing/VoidMethodStubbableImpl.java b/src/org/mockito/internal/stubbing/VoidMethodStubbableImpl.java
index 3859fed..3da5a41 100644
--- a/src/org/mockito/internal/stubbing/VoidMethodStubbableImpl.java
+++ b/src/org/mockito/internal/stubbing/VoidMethodStubbableImpl.java
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.stubbing;
import org.mockito.internal.stubbing.answers.DoesNothing;
@@ -11,7 +11,7 @@
public class VoidMethodStubbableImpl<T> implements VoidMethodStubbable<T> {
private final T mock;
- private InvocationContainerImpl invocationContainerImpl;
+ private final InvocationContainerImpl invocationContainerImpl;
public VoidMethodStubbableImpl(T mock, InvocationContainerImpl invocationContainerImpl) {
this.mock = mock;
diff --git a/src/org/mockito/internal/stubbing/answers/AnswersValidator.java b/src/org/mockito/internal/stubbing/answers/AnswersValidator.java
index b8f5b7a..57adb38 100644
--- a/src/org/mockito/internal/stubbing/answers/AnswersValidator.java
+++ b/src/org/mockito/internal/stubbing/answers/AnswersValidator.java
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.stubbing.answers;
import org.mockito.exceptions.Reporter;
@@ -10,7 +10,7 @@
public class AnswersValidator {
- private Reporter reporter = new Reporter();
+ private final Reporter reporter = new Reporter();
public void validate(Answer<?> answer, Invocation invocation) {
MethodInfo methodInfo = new MethodInfo(invocation);
@@ -49,8 +49,8 @@
}
private void validateMockingConcreteClass(CallsRealMethods answer, MethodInfo methodInfo) {
- if (methodInfo.isDeclaredOnInterface()) {
- reporter.cannotCallRealMethodOnInterface();
+ if (methodInfo.isAbstract()) {
+ reporter.cannotCallAbstractRealMethod();
}
}
diff --git a/src/org/mockito/internal/stubbing/answers/CallsRealMethods.java b/src/org/mockito/internal/stubbing/answers/CallsRealMethods.java
index 14e12dd..167e67b 100644
--- a/src/org/mockito/internal/stubbing/answers/CallsRealMethods.java
+++ b/src/org/mockito/internal/stubbing/answers/CallsRealMethods.java
@@ -1,14 +1,16 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.stubbing.answers;
-import java.io.Serializable;
-
+import org.mockito.Answers;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
+import java.io.Serializable;
+import java.lang.reflect.Modifier;
+
/**
* Optional Answer that adds partial mocking support
* <p>
@@ -33,6 +35,9 @@
private static final long serialVersionUID = 9057165148930624087L;
public Object answer(InvocationOnMock invocation) throws Throwable {
+ if (Modifier.isAbstract(invocation.getMethod().getModifiers())) {
+ return Answers.RETURNS_DEFAULTS.get().answer(invocation);
+ }
return invocation.callRealMethod();
}
}
\ No newline at end of file
diff --git a/src/org/mockito/internal/stubbing/answers/MethodInfo.java b/src/org/mockito/internal/stubbing/answers/MethodInfo.java
index a27e0bb..39b2f51 100644
--- a/src/org/mockito/internal/stubbing/answers/MethodInfo.java
+++ b/src/org/mockito/internal/stubbing/answers/MethodInfo.java
@@ -4,17 +4,19 @@
*/
package org.mockito.internal.stubbing.answers;
+import org.mockito.internal.invocation.AbstractAwareMethod;
import org.mockito.internal.util.Primitives;
import org.mockito.invocation.Invocation;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
/**
* by Szczepan Faber, created at: 3/31/12
*/
-public class MethodInfo {
+public class MethodInfo implements AbstractAwareMethod {
- private Method method;
+ private final Method method;
public MethodInfo(Invocation theInvocation) {
this.method = theInvocation.getMethod();
@@ -63,4 +65,8 @@
public boolean isDeclaredOnInterface() {
return method.getDeclaringClass().isInterface();
}
+
+ public boolean isAbstract() {
+ return (method.getModifiers() & Modifier.ABSTRACT) != 0;
+ }
}
diff --git a/src/org/mockito/internal/stubbing/answers/ThrowsExceptionClass.java b/src/org/mockito/internal/stubbing/answers/ThrowsExceptionClass.java
index 3b1af82..1059844 100644
--- a/src/org/mockito/internal/stubbing/answers/ThrowsExceptionClass.java
+++ b/src/org/mockito/internal/stubbing/answers/ThrowsExceptionClass.java
@@ -14,16 +14,15 @@
public class ThrowsExceptionClass implements Answer<Object>, Serializable {
- private Class<? extends Throwable> throwableClass;
+ private final Class<? extends Throwable> throwableClass;
private final ConditionalStackTraceFilter filter = new ConditionalStackTraceFilter();
public ThrowsExceptionClass(Class<? extends Throwable> throwableClass) {
-
this.throwableClass = throwableClass;
}
public Object answer(InvocationOnMock invocation) throws Throwable {
-
+ //TODO centralize the use of Objenesis. Why do we use ObjenesisHelper?
Throwable throwable = (Throwable) ObjenesisHelper.newInstance(throwableClass);
throwable.fillInStackTrace();
filter.filter(throwable);
diff --git a/src/org/mockito/internal/stubbing/defaultanswers/Answers.java b/src/org/mockito/internal/stubbing/defaultanswers/Answers.java
index bf2ff6b..a72d583 100644
--- a/src/org/mockito/internal/stubbing/defaultanswers/Answers.java
+++ b/src/org/mockito/internal/stubbing/defaultanswers/Answers.java
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.stubbing.defaultanswers;
import org.mockito.Mockito;
@@ -27,7 +27,7 @@
CALLS_REAL_METHODS(new CallsRealMethods())
;
- private Answer<Object> implementation;
+ private final Answer<Object> implementation;
private Answers(Answer<Object> implementation) {
this.implementation = implementation;
diff --git a/src/org/mockito/internal/stubbing/defaultanswers/ForwardsInvocations.java b/src/org/mockito/internal/stubbing/defaultanswers/ForwardsInvocations.java
index b3cd3e8..df86442 100644
--- a/src/org/mockito/internal/stubbing/defaultanswers/ForwardsInvocations.java
+++ b/src/org/mockito/internal/stubbing/defaultanswers/ForwardsInvocations.java
@@ -4,30 +4,65 @@
*/
package org.mockito.internal.stubbing.defaultanswers;
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.mockito.exceptions.Reporter;
+import org.mockito.exceptions.base.MockitoException;
+import org.mockito.internal.stubbing.answers.MethodInfo;
+import org.mockito.internal.util.Primitives;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
-import java.io.Serializable;
-import java.lang.reflect.Method;
-
/**
* Internal answer to forward invocations on a real instance.
*
* @since 1.9.5
*/
public class ForwardsInvocations implements Answer<Object>, Serializable {
+ private static final long serialVersionUID = -8343690268123254910L;
- private static final long serialVersionUID = -8343690268123254910L;
+ private Object delegatedObject = null ;
- private Object delegatedObject = null ;
+ public ForwardsInvocations(Object delegatedObject) {
+ this.delegatedObject = delegatedObject ;
+ }
- public ForwardsInvocations(Object delegatedObject) {
- this.delegatedObject = delegatedObject ;
- }
+ public Object answer(InvocationOnMock invocation) throws Throwable {
+ Method mockMethod = invocation.getMethod();
+
+ Object result = null;
+
+ try {
+ Method delegateMethod = getDelegateMethod(mockMethod);
+
+ if (!compatibleReturnTypes(mockMethod.getReturnType(), delegateMethod.getReturnType())) {
+ new Reporter().delegatedMethodHasWrongReturnType(mockMethod, delegateMethod, invocation.getMock(), delegatedObject);
+ }
+
+ result = delegateMethod.invoke(delegatedObject, invocation.getArguments());
+ } catch (NoSuchMethodException e) {
+ new Reporter().delegatedMethodDoesNotExistOnDelegate(mockMethod, invocation.getMock(), delegatedObject);
+ } catch (InvocationTargetException e) {
+ // propagate the original exception from the delegate
+ throw e.getCause();
+ }
+
+ return result;
+ }
- public Object answer(InvocationOnMock invocation) throws Throwable {
- Method method = invocation.getMethod() ;
+ private Method getDelegateMethod(Method mockMethod) throws NoSuchMethodException {
+ if (mockMethod.getDeclaringClass().isAssignableFrom(delegatedObject.getClass())) {
+ // Compatible class. Return original method.
+ return mockMethod;
+ } else {
+ // Return method of delegate object with the same signature as mockMethod.
+ return delegatedObject.getClass().getMethod(mockMethod.getName(), mockMethod.getParameterTypes());
+ }
+ }
- return method.invoke(delegatedObject, invocation.getArguments());
- }
-}
\ No newline at end of file
+ private static boolean compatibleReturnTypes(Class<?> superType, Class<?> subType) {
+ return superType.equals(subType) || superType.isAssignableFrom(subType);
+ }
+}
diff --git a/src/org/mockito/internal/stubbing/defaultanswers/ReturnsDeepStubs.java b/src/org/mockito/internal/stubbing/defaultanswers/ReturnsDeepStubs.java
index b08af1b..3bb7636 100644
--- a/src/org/mockito/internal/stubbing/defaultanswers/ReturnsDeepStubs.java
+++ b/src/org/mockito/internal/stubbing/defaultanswers/ReturnsDeepStubs.java
@@ -5,6 +5,7 @@
package org.mockito.internal.stubbing.defaultanswers;
import org.mockito.MockSettings;
+import org.mockito.Mockito;
import org.mockito.internal.InternalMockHandler;
import org.mockito.internal.MockitoCore;
import org.mockito.internal.creation.settings.CreationSettings;
@@ -13,8 +14,10 @@
import org.mockito.internal.util.MockUtil;
import org.mockito.internal.util.reflection.GenericMetadataSupport;
import org.mockito.invocation.InvocationOnMock;
+import org.mockito.mock.MockCreationSettings;
import org.mockito.stubbing.Answer;
+import java.io.IOException;
import java.io.Serializable;
import static org.mockito.Mockito.withSettings;
@@ -38,37 +41,37 @@
* @see org.mockito.Answers#RETURNS_DEEP_STUBS
*/
public class ReturnsDeepStubs implements Answer<Object>, Serializable {
-
- private static final long serialVersionUID = -7105341425736035847L;
- private MockitoCore mockitoCore = new MockitoCore();
- private ReturnsEmptyValues delegate = new ReturnsEmptyValues();
+ private static final long serialVersionUID = -7105341425736035847L;
public Object answer(InvocationOnMock invocation) throws Throwable {
GenericMetadataSupport returnTypeGenericMetadata =
actualParameterizedType(invocation.getMock()).resolveGenericReturnType(invocation.getMethod());
Class<?> rawType = returnTypeGenericMetadata.rawType();
- if (!mockitoCore.isTypeMockable(rawType)) {
- return delegate.returnValueFor(rawType);
+ if (!mockitoCore().isTypeMockable(rawType)) {
+ return delegate().returnValueFor(rawType);
}
- return getMock(invocation, returnTypeGenericMetadata);
+ return deepStub(invocation, returnTypeGenericMetadata);
}
- private Object getMock(InvocationOnMock invocation, GenericMetadataSupport returnTypeGenericMetadata) throws Throwable {
- InternalMockHandler<Object> handler = new MockUtil().getMockHandler(invocation.getMock());
- InvocationContainerImpl container = (InvocationContainerImpl) handler.getInvocationContainer();
+ private Object deepStub(InvocationOnMock invocation, GenericMetadataSupport returnTypeGenericMetadata) throws Throwable {
+ InternalMockHandler<Object> handler = new MockUtil().getMockHandler(invocation.getMock());
+ InvocationContainerImpl container = (InvocationContainerImpl) handler.getInvocationContainer();
// matches invocation for verification
for (StubbedInvocationMatcher stubbedInvocationMatcher : container.getStubbedInvocations()) {
- if(container.getInvocationForStubbing().matches(stubbedInvocationMatcher.getInvocation())) {
- return stubbedInvocationMatcher.answer(invocation);
- }
- }
+ if (container.getInvocationForStubbing().matches(stubbedInvocationMatcher.getInvocation())) {
+ return stubbedInvocationMatcher.answer(invocation);
+ }
+ }
- // deep stub
- return recordDeepStubMock(createNewDeepStubMock(returnTypeGenericMetadata), container);
+ // record deep stub answer
+ return recordDeepStubAnswer(
+ newDeepStubMock(returnTypeGenericMetadata, invocation.getMock()),
+ container
+ );
}
/**
@@ -79,42 +82,36 @@
* {@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.
* @return The mock
*/
- private Object createNewDeepStubMock(GenericMetadataSupport returnTypeGenericMetadata) {
- return mockitoCore.mock(
+ private Object newDeepStubMock(GenericMetadataSupport returnTypeGenericMetadata, Object parentMock) {
+ MockCreationSettings parentMockSettings = new MockUtil().getMockSettings(parentMock);
+ return mockitoCore().mock(
returnTypeGenericMetadata.rawType(),
- withSettingsUsing(returnTypeGenericMetadata)
+ withSettingsUsing(returnTypeGenericMetadata, parentMockSettings)
);
}
- private MockSettings withSettingsUsing(GenericMetadataSupport returnTypeGenericMetadata) {
- MockSettings mockSettings =
- returnTypeGenericMetadata.rawExtraInterfaces().length > 0 ?
+ private MockSettings withSettingsUsing(GenericMetadataSupport returnTypeGenericMetadata, MockCreationSettings parentMockSettings) {
+ MockSettings mockSettings = returnTypeGenericMetadata.hasRawExtraInterfaces() ?
withSettings().extraInterfaces(returnTypeGenericMetadata.rawExtraInterfaces())
: withSettings();
- return mockSettings
+ return propagateSerializationSettings(mockSettings, parentMockSettings)
.defaultAnswer(returnsDeepStubsAnswerUsing(returnTypeGenericMetadata));
}
- private ReturnsDeepStubs returnsDeepStubsAnswerUsing(final GenericMetadataSupport returnTypeGenericMetadata) {
- return new ReturnsDeepStubs() {
- @Override
- protected GenericMetadataSupport actualParameterizedType(Object mock) {
- return returnTypeGenericMetadata;
- }
- };
+ private MockSettings propagateSerializationSettings(MockSettings mockSettings, MockCreationSettings parentMockSettings) {
+ return mockSettings.serializable(parentMockSettings.getSerializableMode());
}
- private Object recordDeepStubMock(final Object mock, InvocationContainerImpl container) throws Throwable {
+ private ReturnsDeepStubs returnsDeepStubsAnswerUsing(final GenericMetadataSupport returnTypeGenericMetadata) {
+ return new ReturnsDeepStubsSerializationFallback(returnTypeGenericMetadata);
+ }
- container.addAnswer(new Answer<Object>() {
- public Object answer(InvocationOnMock invocation) throws Throwable {
- return mock;
- }
- }, false);
-
+ private Object recordDeepStubAnswer(final Object mock, InvocationContainerImpl container) throws Throwable {
+ container.addAnswer(new DeeplyStubbedAnswer(mock), false);
return mock;
}
@@ -122,4 +119,49 @@
CreationSettings mockSettings = (CreationSettings) new MockUtil().getMockHandler(mock).getMockSettings();
return GenericMetadataSupport.inferFrom(mockSettings.getTypeToMock());
}
+
+
+ private static class ReturnsDeepStubsSerializationFallback extends ReturnsDeepStubs implements Serializable {
+ @SuppressWarnings("serial") // not gonna be serialized
+ private final GenericMetadataSupport returnTypeGenericMetadata;
+
+ public ReturnsDeepStubsSerializationFallback(GenericMetadataSupport returnTypeGenericMetadata) {
+ this.returnTypeGenericMetadata = returnTypeGenericMetadata;
+ }
+
+ @Override
+ protected GenericMetadataSupport actualParameterizedType(Object mock) {
+ return returnTypeGenericMetadata;
+ }
+ private Object writeReplace() throws IOException {
+ return Mockito.RETURNS_DEEP_STUBS;
+ }
+ }
+
+
+ private static class DeeplyStubbedAnswer implements Answer<Object>, Serializable {
+ @SuppressWarnings("serial") // serialization will fail with a nice message if mock not serializable
+ private final Object mock;
+
+ DeeplyStubbedAnswer(Object mock) {
+ this.mock = mock;
+ }
+ public Object answer(InvocationOnMock invocation) throws Throwable {
+ return mock;
+ }
+ }
+
+
+ private static MockitoCore mockitoCore() {
+ return LazyHolder.MOCKITO_CORE;
+ }
+
+ private static ReturnsEmptyValues delegate() {
+ return LazyHolder.DELEGATE;
+ }
+
+ private static class LazyHolder {
+ private static final MockitoCore MOCKITO_CORE = new MockitoCore();
+ private static final ReturnsEmptyValues DELEGATE = new ReturnsEmptyValues();
+ }
}
diff --git a/src/org/mockito/internal/stubbing/defaultanswers/ReturnsEmptyValues.java b/src/org/mockito/internal/stubbing/defaultanswers/ReturnsEmptyValues.java
index 87905b6..d19fcda 100644
--- a/src/org/mockito/internal/stubbing/defaultanswers/ReturnsEmptyValues.java
+++ b/src/org/mockito/internal/stubbing/defaultanswers/ReturnsEmptyValues.java
@@ -44,7 +44,7 @@
* Returns description of mock for toString() method
* </li>
* <li>
- * Returns non-zero for Comparable#compareTo(T other) method (see issue 184)
+ * Returns zero if references are equals otherwise non-zero for Comparable#compareTo(T other) method (see issue 184)
* </li>
* <li>
* Returns null for everything else
@@ -71,9 +71,9 @@
}
} else if (methodsGuru.isCompareToMethod(invocation.getMethod())) {
//see issue 184.
- //mocks by default should not return 0 for compareTo because they are not the same. Hence we return 1 (anything but 0 is good).
+ //mocks by default should return 0 if references are the same, otherwise some other value because they are not the same. Hence we return 1 (anything but 0 is good).
//Only for compareTo() method by the Comparable interface
- return 1;
+ return invocation.getMock() == invocation.getArguments()[0] ? 0 : 1;
}
Class<?> returnType = invocation.getMethod().getReturnType();
diff --git a/src/org/mockito/internal/stubbing/defaultanswers/ReturnsMocks.java b/src/org/mockito/internal/stubbing/defaultanswers/ReturnsMocks.java
index 20168a4..e6a585f 100755
--- a/src/org/mockito/internal/stubbing/defaultanswers/ReturnsMocks.java
+++ b/src/org/mockito/internal/stubbing/defaultanswers/ReturnsMocks.java
@@ -1,21 +1,21 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * 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.io.Serializable;
-
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 MockitoCore mockitoCore = new MockitoCore();
- private Answer<Object> delegate = new ReturnsMoreEmptyValues();
+ private final MockitoCore mockitoCore = new MockitoCore();
+ private final Answer<Object> delegate = new ReturnsMoreEmptyValues();
public Object answer(InvocationOnMock invocation) throws Throwable {
Object ret = delegate.answer(invocation);
@@ -33,4 +33,4 @@
return mockitoCore.mock(clazz, new MockSettingsImpl().defaultAnswer(this));
}
-}
+}
diff --git a/src/org/mockito/internal/stubbing/defaultanswers/ReturnsMoreEmptyValues.java b/src/org/mockito/internal/stubbing/defaultanswers/ReturnsMoreEmptyValues.java
index 194db14..39c0247 100644
--- a/src/org/mockito/internal/stubbing/defaultanswers/ReturnsMoreEmptyValues.java
+++ b/src/org/mockito/internal/stubbing/defaultanswers/ReturnsMoreEmptyValues.java
@@ -5,13 +5,13 @@
package org.mockito.internal.stubbing.defaultanswers;
-import java.io.Serializable;
-import java.lang.reflect.Array;
-
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+
/**
* It's likely this implementation will be used by default by every Mockito 2.0 mock.
* <p>
@@ -48,7 +48,7 @@
public class ReturnsMoreEmptyValues implements Answer<Object>, Serializable {
private static final long serialVersionUID = -2816745041482698471L;
- private Answer<Object> delegate = new ReturnsEmptyValues();
+ private final Answer<Object> delegate = new ReturnsEmptyValues();
/* (non-Javadoc)
* @see org.mockito.stubbing.Answer#answer(org.mockito.invocation.InvocationOnMock)
diff --git a/src/org/mockito/internal/util/DefaultMockingDetails.java b/src/org/mockito/internal/util/DefaultMockingDetails.java
index 0de3343..e361c6e 100644
--- a/src/org/mockito/internal/util/DefaultMockingDetails.java
+++ b/src/org/mockito/internal/util/DefaultMockingDetails.java
@@ -1,10 +1,13 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.util;
import org.mockito.MockingDetails;
+import org.mockito.invocation.Invocation;
+
+import java.util.Collection;
/**
* Class to inspect any object, and identify whether a particular object is either a mock or a spy. This is
@@ -12,8 +15,8 @@
*/
public class DefaultMockingDetails implements MockingDetails {
- private Object toInspect;
- private MockUtil delegate;
+ private final Object toInspect;
+ private final MockUtil delegate;
public DefaultMockingDetails(Object toInspect, MockUtil delegate){
this.toInspect = toInspect;
@@ -34,5 +37,9 @@
public boolean isSpy(){
return delegate.isSpy( toInspect );
}
+
+ public Collection<Invocation> getInvocations() {
+ return delegate.getMockHandler(toInspect).getInvocationContainer().getInvocations();
+ }
}
diff --git a/src/org/mockito/internal/util/MockCreationValidator.java b/src/org/mockito/internal/util/MockCreationValidator.java
index d3a535a..35d99d9 100644
--- a/src/org/mockito/internal/util/MockCreationValidator.java
+++ b/src/org/mockito/internal/util/MockCreationValidator.java
@@ -6,6 +6,7 @@
import org.mockito.exceptions.Reporter;
import org.mockito.internal.util.reflection.Constructors;
+import org.mockito.mock.SerializableMode;
import java.io.Serializable;
import java.util.Collection;
@@ -63,4 +64,10 @@
new Reporter().serializableWontWorkForObjectsThatDontImplementSerializable(classToMock);
}
}
+
+ public void validateConstructorUse(boolean usingConstructor, SerializableMode mode) {
+ if (usingConstructor && mode == SerializableMode.ACROSS_CLASSLOADERS) {
+ new Reporter().usingConstructorWithFancySerializable(mode);
+ }
+ }
}
\ No newline at end of file
diff --git a/src/org/mockito/internal/util/MockUtil.java b/src/org/mockito/internal/util/MockUtil.java
index e62b3d6..433be78 100644
--- a/src/org/mockito/internal/util/MockUtil.java
+++ b/src/org/mockito/internal/util/MockUtil.java
@@ -4,9 +4,10 @@
*/
package org.mockito.internal.util;
+import org.mockito.Mockito;
import org.mockito.exceptions.misusing.NotAMockException;
import org.mockito.internal.InternalMockHandler;
-import org.mockito.internal.configuration.ClassPathLoader;
+import org.mockito.internal.configuration.plugins.Plugins;
import org.mockito.internal.creation.settings.CreationSettings;
import org.mockito.internal.handler.MockHandlerFactory;
import org.mockito.internal.util.reflection.LenientCopyTool;
@@ -14,17 +15,17 @@
import org.mockito.mock.MockCreationSettings;
import org.mockito.mock.MockName;
import org.mockito.plugins.MockMaker;
-
-import java.lang.reflect.Modifier;
+
+import java.lang.reflect.Modifier;
@SuppressWarnings("unchecked")
public class MockUtil {
- private static final MockMaker mockMaker = ClassPathLoader.getMockMaker();
-
- public boolean isTypeMockable(Class<?> type) {
- return !type.isPrimitive() && !Modifier.isFinal(type.getModifiers());
- }
+ private static final MockMaker mockMaker = Plugins.getMockMaker();
+
+ public boolean isTypeMockable(Class<?> type) {
+ return !type.isPrimitive() && !Modifier.isFinal(type.getModifiers());
+ }
public <T> T createMock(MockCreationSettings<T> settings) {
MockHandler mockHandler = new MockHandlerFactory().create(settings);
@@ -53,7 +54,8 @@
}
if (isMockitoMock(mock)) {
- return (InternalMockHandler) mockMaker.getHandler(mock);
+ MockHandler handler = mockMaker.getHandler(mock);
+ return (InternalMockHandler) handler;
} else {
throw new NotAMockException("Argument should be a mock, but is: " + mock.getClass());
}
@@ -61,19 +63,11 @@
public boolean isMock(Object mock) {
// double check to avoid classes that have the same interfaces, could be great to have a custom mockito field in the proxy instead of relying on instance fields
- return mock instanceof MockitoMock && isMockitoMock(mock);
+ return isMockitoMock(mock);
}
public boolean isSpy(Object mock) {
- return mock instanceof MockitoSpy;
- }
-
- public boolean isMock(Class mockClass) {
- return mockClass != null && MockitoMock.class.isAssignableFrom(mockClass);
- }
-
- public boolean isSpy(Class mockClass) {
- return mockClass != null && MockitoSpy.class.isAssignableFrom(mockClass);
+ return isMockitoMock(mock) && getMockSettings(mock).getDefaultAnswer() == Mockito.CALLS_REAL_METHODS;
}
private <T> boolean isMockitoMock(T mock) {
diff --git a/src/org/mockito/internal/util/MockitoMock.java b/src/org/mockito/internal/util/MockitoMock.java
deleted file mode 100644
index 05f1d51..0000000
--- a/src/org/mockito/internal/util/MockitoMock.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.mockito.internal.util;
-
-/**
- * Mark internally a Mockito mock.
- *
- * To be used un conjunction with {@link MockUtil#isMock(Object)}
- */
-public interface MockitoMock {
-}
diff --git a/src/org/mockito/internal/util/MockitoSpy.java b/src/org/mockito/internal/util/MockitoSpy.java
deleted file mode 100644
index 30d8362..0000000
--- a/src/org/mockito/internal/util/MockitoSpy.java
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
-package org.mockito.internal.util;
-
-/**
- * Mark internally a Mockito spy.
- *
- * To be used un conjunction with {@link MockUtil#isMock(Object)} or {@link MockUtil#isSpy(Object)}.
- */
-public interface MockitoSpy extends MockitoMock {
-}
diff --git a/src/org/mockito/internal/util/Primitives.java b/src/org/mockito/internal/util/Primitives.java
index 9b444cf..4dcc07e 100644
--- a/src/org/mockito/internal/util/Primitives.java
+++ b/src/org/mockito/internal/util/Primitives.java
@@ -10,8 +10,8 @@
@SuppressWarnings("unchecked")
public class Primitives {
- private static Map<Class<?>, Class<?>> primitiveTypes = new HashMap<Class<?>, Class<?>>();
- private static Map<Class<?>, Object> primitiveOrWrapperDefaultValues = new HashMap<Class<?>, Object>();
+ private static final Map<Class<?>, Class<?>> PRIMITIVE_TYPES = new HashMap<Class<?>, Class<?>>();
+ private static final Map<Class<?>, Object> PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES = new HashMap<Class<?>, Object>();
/**
@@ -29,7 +29,7 @@
if (clazz.isPrimitive()) {
return clazz;
}
- return (Class<T>) primitiveTypes.get(clazz);
+ return (Class<T>) PRIMITIVE_TYPES.get(clazz);
}
/**
@@ -39,7 +39,7 @@
* @return <code>true</code> if primitive or wrapper, <code>false</code> otherwise.
*/
public static boolean isPrimitiveOrWrapper(Class<?> type) {
- return primitiveOrWrapperDefaultValues.containsKey(type);
+ return PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.containsKey(type);
}
/**
@@ -50,38 +50,38 @@
* <code>null</code> if the type is neither a primitive nor a wrapper
*/
public static <T> T defaultValueForPrimitiveOrWrapper(Class<T> primitiveOrWrapperType) {
- return (T) primitiveOrWrapperDefaultValues.get(primitiveOrWrapperType);
+ return (T) PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.get(primitiveOrWrapperType);
}
static {
- primitiveTypes.put(Boolean.class, Boolean.TYPE);
- primitiveTypes.put(Character.class, Character.TYPE);
- primitiveTypes.put(Byte.class, Byte.TYPE);
- primitiveTypes.put(Short.class, Short.TYPE);
- primitiveTypes.put(Integer.class, Integer.TYPE);
- primitiveTypes.put(Long.class, Long.TYPE);
- primitiveTypes.put(Float.class, Float.TYPE);
- primitiveTypes.put(Double.class, Double.TYPE);
+ PRIMITIVE_TYPES.put(Boolean.class, Boolean.TYPE);
+ PRIMITIVE_TYPES.put(Character.class, Character.TYPE);
+ PRIMITIVE_TYPES.put(Byte.class, Byte.TYPE);
+ PRIMITIVE_TYPES.put(Short.class, Short.TYPE);
+ PRIMITIVE_TYPES.put(Integer.class, Integer.TYPE);
+ PRIMITIVE_TYPES.put(Long.class, Long.TYPE);
+ PRIMITIVE_TYPES.put(Float.class, Float.TYPE);
+ PRIMITIVE_TYPES.put(Double.class, Double.TYPE);
}
static {
- primitiveOrWrapperDefaultValues.put(Boolean.class, false);
- primitiveOrWrapperDefaultValues.put(Character.class, '\u0000');
- primitiveOrWrapperDefaultValues.put(Byte.class, (byte) 0);
- primitiveOrWrapperDefaultValues.put(Short.class, (short) 0);
- primitiveOrWrapperDefaultValues.put(Integer.class, 0);
- primitiveOrWrapperDefaultValues.put(Long.class, 0L);
- primitiveOrWrapperDefaultValues.put(Float.class, 0F);
- primitiveOrWrapperDefaultValues.put(Double.class, 0D);
+ PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(Boolean.class, false);
+ PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(Character.class, '\u0000');
+ PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(Byte.class, (byte) 0);
+ PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(Short.class, (short) 0);
+ PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(Integer.class, 0);
+ PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(Long.class, 0L);
+ PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(Float.class, 0F);
+ PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(Double.class, 0D);
- primitiveOrWrapperDefaultValues.put(boolean.class, false);
- primitiveOrWrapperDefaultValues.put(char.class, '\u0000');
- primitiveOrWrapperDefaultValues.put(byte.class, (byte) 0);
- primitiveOrWrapperDefaultValues.put(short.class, (short) 0);
- primitiveOrWrapperDefaultValues.put(int.class, 0);
- primitiveOrWrapperDefaultValues.put(long.class, 0L);
- primitiveOrWrapperDefaultValues.put(float.class, 0F);
- primitiveOrWrapperDefaultValues.put(double.class, 0D);
+ PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(boolean.class, false);
+ PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(char.class, '\u0000');
+ PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(byte.class, (byte) 0);
+ PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(short.class, (short) 0);
+ PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(int.class, 0);
+ PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(long.class, 0L);
+ PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(float.class, 0F);
+ PRIMITIVE_OR_WRAPPER_DEFAULT_VALUES.put(double.class, 0D);
}
}
\ No newline at end of file
diff --git a/src/org/mockito/internal/util/Timer.java b/src/org/mockito/internal/util/Timer.java
new file mode 100644
index 0000000..b71e4fd
--- /dev/null
+++ b/src/org/mockito/internal/util/Timer.java
@@ -0,0 +1,26 @@
+package org.mockito.internal.util;
+
+public class Timer {
+
+ private final long durationMillis;
+ private long startTime = -1;
+
+ public Timer(long durationMillis) {
+ this.durationMillis = durationMillis;
+ }
+
+ /**
+ * Informs whether the timer is still counting down.
+ */
+ public boolean isCounting() {
+ assert startTime != -1;
+ return System.currentTimeMillis() - startTime <= durationMillis;
+ }
+
+ /**
+ * Starts the timer count down.
+ */
+ public void start() {
+ startTime = System.currentTimeMillis();
+ }
+}
diff --git a/src/org/mockito/internal/util/collections/HashCodeAndEqualsMockWrapper.java b/src/org/mockito/internal/util/collections/HashCodeAndEqualsMockWrapper.java
index 251c2a0..22c9d1b 100644
--- a/src/org/mockito/internal/util/collections/HashCodeAndEqualsMockWrapper.java
+++ b/src/org/mockito/internal/util/collections/HashCodeAndEqualsMockWrapper.java
@@ -26,7 +26,7 @@
*/
public class HashCodeAndEqualsMockWrapper {
- private Object mockInstance;
+ private final Object mockInstance;
public HashCodeAndEqualsMockWrapper(Object mockInstance) {
this.mockInstance = mockInstance;
diff --git a/src/org/mockito/internal/util/collections/HashCodeAndEqualsSafeSet.java b/src/org/mockito/internal/util/collections/HashCodeAndEqualsSafeSet.java
index d9c82cf..466c11a 100644
--- a/src/org/mockito/internal/util/collections/HashCodeAndEqualsSafeSet.java
+++ b/src/org/mockito/internal/util/collections/HashCodeAndEqualsSafeSet.java
@@ -31,11 +31,11 @@
*/
public class HashCodeAndEqualsSafeSet implements Set<Object> {
- private HashSet<HashCodeAndEqualsMockWrapper> backingHashSet = new HashSet<HashCodeAndEqualsMockWrapper>();
+ private final HashSet<HashCodeAndEqualsMockWrapper> backingHashSet = new HashSet<HashCodeAndEqualsMockWrapper>();
public Iterator<Object> iterator() {
return new Iterator<Object>() {
- private Iterator<HashCodeAndEqualsMockWrapper> iterator = backingHashSet.iterator();
+ private final Iterator<HashCodeAndEqualsMockWrapper> iterator = backingHashSet.iterator();
public boolean hasNext() {
return iterator.hasNext();
diff --git a/src/org/mockito/internal/util/collections/Iterables.java b/src/org/mockito/internal/util/collections/Iterables.java
new file mode 100644
index 0000000..9aba368
--- /dev/null
+++ b/src/org/mockito/internal/util/collections/Iterables.java
@@ -0,0 +1,22 @@
+package org.mockito.internal.util.collections;
+
+import java.util.Enumeration;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Utilities for Iterables
+ */
+public class Iterables {
+
+ /**
+ * Converts enumeration into iterable
+ */
+ public static <T> Iterable<T> toIterable(Enumeration<T> in) {
+ List<T> out = new LinkedList<T>();
+ while(in.hasMoreElements()) {
+ out.add(in.nextElement());
+ }
+ return out;
+ }
+}
diff --git a/src/org/mockito/internal/util/collections/ListUtil.java b/src/org/mockito/internal/util/collections/ListUtil.java
index 6b492c6..b426bb2 100644
--- a/src/org/mockito/internal/util/collections/ListUtil.java
+++ b/src/org/mockito/internal/util/collections/ListUtil.java
@@ -20,7 +20,7 @@
return filtered;
}
- public static interface Filter<T> {
+ public interface Filter<T> {
boolean isOut(T object);
}
}
diff --git a/src/org/mockito/internal/util/io/IOUtil.java b/src/org/mockito/internal/util/io/IOUtil.java
new file mode 100644
index 0000000..2b90c2c
--- /dev/null
+++ b/src/org/mockito/internal/util/io/IOUtil.java
@@ -0,0 +1,71 @@
+package org.mockito.internal.util.io;
+
+import org.mockito.exceptions.base.MockitoException;
+
+import java.io.*;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * IO utils. A bit of reinventing the wheel but we don't want extra dependencies at this stage and we want to be java.
+ */
+public class IOUtil {
+
+ /**
+ * Writes text to file
+ */
+ public static void writeText(String text, File output) {
+ PrintWriter pw = null;
+ try {
+ pw = new PrintWriter(new FileWriter(output));
+ pw.write(text);
+ } catch (Exception e) {
+ throw new MockitoException("Problems writing text to file: " + output, e);
+ } finally {
+ close(pw);
+ }
+ }
+
+ public static Collection<String> readLines(InputStream is) {
+ List<String> out = new LinkedList<String>();
+ BufferedReader r = new BufferedReader(new InputStreamReader(is));
+ String line;
+ try {
+ while((line = r.readLine()) != null) {
+ out.add(line);
+ }
+ } catch (IOException e) {
+ throw new MockitoException("Problems reading from: " + is, e);
+ }
+ return out;
+ }
+
+ /**
+ * Closes the target. Does nothing when target is null. Is silent.
+ *
+ * @param closeable the target, may be null
+ */
+ public static void closeQuietly(Closeable closeable) {
+ try {
+ close(closeable);
+ } catch (MockitoException ignored) {
+ //ignore, for backwards compatibility
+ }
+ }
+
+ /**
+ * Closes the target. Does nothing when target is null. Is not silent and exceptions are rethrown.
+ *
+ * @param closeable the target, may be null
+ */
+ public static void close(Closeable closeable) {
+ if (closeable != null) {
+ try {
+ closeable.close();
+ } catch (IOException e) {
+ throw new MockitoException("Problems closing stream: " + closeable, e);
+ }
+ }
+ }
+}
diff --git a/src/org/mockito/internal/util/reflection/BeanPropertySetter.java b/src/org/mockito/internal/util/reflection/BeanPropertySetter.java
index d84d57a..082231d 100644
--- a/src/org/mockito/internal/util/reflection/BeanPropertySetter.java
+++ b/src/org/mockito/internal/util/reflection/BeanPropertySetter.java
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.util.reflection;
import java.lang.reflect.Field;
@@ -17,7 +17,7 @@
private static final String SET_PREFIX = "set";
private final Object target;
- private boolean reportNoSetterFound;
+ private final boolean reportNoSetterFound;
private final Field field;
/**
diff --git a/src/org/mockito/internal/util/reflection/FieldInitializationReport.java b/src/org/mockito/internal/util/reflection/FieldInitializationReport.java
index ffe2afd..9a0b778 100644
--- a/src/org/mockito/internal/util/reflection/FieldInitializationReport.java
+++ b/src/org/mockito/internal/util/reflection/FieldInitializationReport.java
@@ -9,9 +9,9 @@
* Report on field initialization
*/
public class FieldInitializationReport {
- private Object fieldInstance;
- private boolean wasInitialized;
- private boolean wasInitializedUsingConstructorArgs;
+ private final Object fieldInstance;
+ private final boolean wasInitialized;
+ private final boolean wasInitializedUsingConstructorArgs;
public FieldInitializationReport(Object fieldInstance, boolean wasInitialized, boolean wasInitializedUsingConstructorArgs) {
this.fieldInstance = fieldInstance;
diff --git a/src/org/mockito/internal/util/reflection/FieldInitializer.java b/src/org/mockito/internal/util/reflection/FieldInitializer.java
index a6d2d44..ec4b68e 100644
--- a/src/org/mockito/internal/util/reflection/FieldInitializer.java
+++ b/src/org/mockito/internal/util/reflection/FieldInitializer.java
@@ -1,10 +1,11 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.util.reflection;
import org.mockito.exceptions.base.MockitoException;
+import org.mockito.internal.util.MockUtil;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
@@ -26,9 +27,9 @@
*/
public class FieldInitializer {
- private Object fieldOwner;
- private Field field;
- private ConstructorInstantiator instantiator;
+ private final Object fieldOwner;
+ private final Field field;
+ private final ConstructorInstantiator instantiator;
/**
@@ -158,8 +159,8 @@
* </p>
*/
static class NoArgConstructorInstantiator implements ConstructorInstantiator {
- private Object testClass;
- private Field field;
+ private final Object testClass;
+ private final Field field;
/**
* Internal, checks are done by FieldInitializer.
@@ -209,13 +210,30 @@
* </p>
*/
static class ParameterizedConstructorInstantiator implements ConstructorInstantiator {
- private Object testClass;
- private Field field;
- private ConstructorArgumentResolver argResolver;
- private Comparator<Constructor<?>> byParameterNumber = new Comparator<Constructor<?>>() {
+ private final Object testClass;
+ private final Field field;
+ private final ConstructorArgumentResolver argResolver;
+ private final MockUtil mockUtil = new MockUtil();
+ private final Comparator<Constructor<?>> byParameterNumber = new Comparator<Constructor<?>>() {
public int compare(Constructor<?> constructorA, Constructor<?> constructorB) {
- return constructorB.getParameterTypes().length - constructorA.getParameterTypes().length;
+ int argLengths = constructorB.getParameterTypes().length - constructorA.getParameterTypes().length;
+ if (argLengths == 0) {
+ int constructorAMockableParamsSize = countMockableParams(constructorA);
+ int constructorBMockableParamsSize = countMockableParams(constructorB);
+ return constructorBMockableParamsSize - constructorAMockableParamsSize;
+ }
+ return argLengths;
}
+
+ private int countMockableParams(Constructor<?> constructor) {
+ int constructorMockableParamsSize = 0;
+ for (Class<?> aClass : constructor.getParameterTypes()) {
+ if(mockUtil.isTypeMockable(aClass)){
+ constructorMockableParamsSize++;
+ }
+ }
+ return constructorMockableParamsSize;
+ }
};
/**
@@ -264,7 +282,7 @@
private Constructor<?> biggestConstructor(Class<?> clazz) {
final List<Constructor<?>> constructors = Arrays.asList(clazz.getDeclaredConstructors());
Collections.sort(constructors, byParameterNumber);
-
+
Constructor<?> constructor = constructors.get(0);
checkParameterized(constructor, field);
return constructor;
diff --git a/src/org/mockito/internal/util/reflection/Fields.java b/src/org/mockito/internal/util/reflection/Fields.java
index 024dc9b..327dac0 100644
--- a/src/org/mockito/internal/util/reflection/Fields.java
+++ b/src/org/mockito/internal/util/reflection/Fields.java
@@ -4,10 +4,9 @@
*/
package org.mockito.internal.util.reflection;
-import org.mockito.Incubating;
import org.mockito.internal.util.Checks;
-import org.mockito.internal.util.collections.ListUtil.Filter;
import org.mockito.internal.util.collections.ListUtil;
+import org.mockito.internal.util.collections.ListUtil.Filter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
@@ -19,7 +18,6 @@
*
* Code is very new and might need rework.
*/
-@Incubating
public abstract class Fields {
/**
diff --git a/src/org/mockito/internal/util/reflection/GenericMaster.java b/src/org/mockito/internal/util/reflection/GenericMaster.java
index 29e384a..2b07930 100644
--- a/src/org/mockito/internal/util/reflection/GenericMaster.java
+++ b/src/org/mockito/internal/util/reflection/GenericMaster.java
@@ -18,7 +18,7 @@
*/
public Class getGenericType(Field field) {
Type generic = field.getGenericType();
- if (generic != null && generic instanceof ParameterizedType) {
+ if (generic instanceof ParameterizedType) {
Type actual = ((ParameterizedType) generic).getActualTypeArguments()[0];
if (actual instanceof Class) {
return (Class) actual;
diff --git a/src/org/mockito/internal/util/reflection/GenericMetadataSupport.java b/src/org/mockito/internal/util/reflection/GenericMetadataSupport.java
index 6cea091..80bd908 100644
--- a/src/org/mockito/internal/util/reflection/GenericMetadataSupport.java
+++ b/src/org/mockito/internal/util/reflection/GenericMetadataSupport.java
@@ -5,7 +5,6 @@
package org.mockito.internal.util.reflection;
-import org.mockito.Incubating;
import org.mockito.exceptions.base.MockitoException;
import org.mockito.internal.util.Checks;
@@ -54,7 +53,6 @@
* @see #resolveGenericReturnType(Method)
* @see org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs
*/
-@Incubating
public abstract class GenericMetadataSupport {
// public static MockitoLogger logger = new ConsoleMockitoLogger();
@@ -78,7 +76,7 @@
if (actualTypeArgument instanceof WildcardType) {
contextualActualTypeParameters.put(typeParameter, boundsOf((WildcardType) actualTypeArgument));
- } else {
+ } else if (typeParameter != actualTypeArgument) {
contextualActualTypeParameters.put(typeParameter, actualTypeArgument);
}
// logger.log("For '" + parameterizedType + "' found type variable : { '" + typeParameter + "(" + System.identityHashCode(typeParameter) + ")" + "' : '" + actualTypeArgument + "(" + System.identityHashCode(typeParameter) + ")" + "' }");
@@ -86,9 +84,15 @@
}
protected void registerTypeParametersOn(TypeVariable[] typeParameters) {
- for (TypeVariable typeParameter : typeParameters) {
- contextualActualTypeParameters.put(typeParameter, boundsOf(typeParameter));
- // logger.log("For '" + typeParameter.getGenericDeclaration() + "' found type variable : { '" + typeParameter + "(" + System.identityHashCode(typeParameter) + ")" + "' : '" + boundsOf(typeParameter) + "' }");
+ for (TypeVariable type : typeParameters) {
+ registerTypeVariableIfNotPresent(type);
+ }
+ }
+
+ private void registerTypeVariableIfNotPresent(TypeVariable typeVariable) {
+ if (!contextualActualTypeParameters.containsKey(typeVariable)) {
+ contextualActualTypeParameters.put(typeVariable, boundsOf(typeVariable));
+ // logger.log("For '" + typeVariable.getGenericDeclaration() + "' found type variable : { '" + typeVariable + "(" + System.identityHashCode(typeVariable) + ")" + "' : '" + boundsOf(typeVariable) + "' }");
}
}
@@ -147,6 +151,13 @@
return new Class[0];
}
+ /**
+ * @return Returns true if metadata knows about extra-interfaces {@link #extraInterfaces()} <strong>if relevant</strong>.
+ */
+ public boolean hasRawExtraInterfaces() {
+ return rawExtraInterfaces().length > 0;
+ }
+
/**
@@ -238,14 +249,29 @@
* the class and its ancestors and interfaces.
*/
private static class FromClassGenericMetadataSupport extends GenericMetadataSupport {
- private Class<?> clazz;
+ private final Class<?> clazz;
public FromClassGenericMetadataSupport(Class<?> clazz) {
this.clazz = clazz;
- readActualTypeParametersOnDeclaringClass();
+
+ for (Class currentExploredClass = clazz;
+ currentExploredClass != null && currentExploredClass != Object.class;
+ currentExploredClass = superClassOf(currentExploredClass)
+ ) {
+ readActualTypeParametersOnDeclaringClass(currentExploredClass);
+ }
}
- private void readActualTypeParametersOnDeclaringClass() {
+ private Class superClassOf(Class currentExploredClass) {
+ Type genericSuperclass = currentExploredClass.getGenericSuperclass();
+ if (genericSuperclass instanceof ParameterizedType) {
+ Type rawType = ((ParameterizedType) genericSuperclass).getRawType();
+ return (Class) rawType;
+ }
+ return (Class) genericSuperclass;
+ }
+
+ private void readActualTypeParametersOnDeclaringClass(Class<?> clazz) {
registerTypeParametersOn(clazz.getTypeParameters());
registerTypeVariablesOn(clazz.getGenericSuperclass());
for (Type genericInterface : clazz.getGenericInterfaces()) {
@@ -272,7 +298,7 @@
* Instead use {@link ParameterizedReturnType}.
*/
private static class FromParameterizedTypeGenericMetadataSupport extends GenericMetadataSupport {
- private ParameterizedType parameterizedType;
+ private final ParameterizedType parameterizedType;
public FromParameterizedTypeGenericMetadataSupport(ParameterizedType parameterizedType) {
this.parameterizedType = parameterizedType;
@@ -350,6 +376,7 @@
for (Type type : typeVariable.getBounds()) {
registerTypeVariablesOn(type);
}
+ registerTypeParametersOn(new TypeVariable[] { typeVariable });
registerTypeVariablesOn(getActualTypeArgumentFor(typeVariable));
}
@@ -460,7 +487,7 @@
* @see WildCardBoundedType
* @see <a href="http://docs.oracle.com/javase/specs/jls/se5.0/html/typesValues.html#4.5.1">http://docs.oracle.com/javase/specs/jls/se5.0/html/typesValues.html#4.5.1</a>
*/
- public static interface BoundedType extends Type {
+ public interface BoundedType extends Type {
Type firstBound();
Type[] interfaceBounds();
@@ -487,7 +514,7 @@
* @see <a href="http://docs.oracle.com/javase/specs/jls/se5.0/html/typesValues.html#4.4">http://docs.oracle.com/javase/specs/jls/se5.0/html/typesValues.html#4.4</a>
*/
public static class TypeVarBoundedType implements BoundedType {
- private TypeVariable typeVariable;
+ private final TypeVariable typeVariable;
public TypeVarBoundedType(TypeVariable typeVariable) {
@@ -530,11 +557,7 @@
@Override
public String toString() {
- final StringBuilder sb = new StringBuilder();
- sb.append("{firstBound=").append(firstBound());
- sb.append(", interfaceBounds=").append(Arrays.deepToString(interfaceBounds()));
- sb.append('}');
- return sb.toString();
+ return "{firstBound=" + firstBound() + ", interfaceBounds=" + Arrays.deepToString(interfaceBounds()) + '}';
}
public TypeVariable typeVariable() {
@@ -551,7 +574,7 @@
* @see <a href="http://docs.oracle.com/javase/specs/jls/se5.0/html/typesValues.html#4.4">http://docs.oracle.com/javase/specs/jls/se5.0/html/typesValues.html#4.4</a>
*/
public static class WildCardBoundedType implements BoundedType {
- private WildcardType wildcard;
+ private final WildcardType wildcard;
public WildCardBoundedType(WildcardType wildcard) {
@@ -591,10 +614,7 @@
@Override
public String toString() {
- final StringBuilder sb = new StringBuilder();
- sb.append("{firstBound=").append(firstBound());
- sb.append(", interfaceBounds=[]}");
- return sb.toString();
+ return "{firstBound=" + firstBound() + ", interfaceBounds=[]}";
}
public WildcardType wildCard() {
diff --git a/src/org/mockito/internal/util/reflection/InstanceField.java b/src/org/mockito/internal/util/reflection/InstanceField.java
index 9e64e19..c3f019d 100644
--- a/src/org/mockito/internal/util/reflection/InstanceField.java
+++ b/src/org/mockito/internal/util/reflection/InstanceField.java
@@ -112,11 +112,7 @@
if (o == null || getClass() != o.getClass()) return false;
InstanceField that = (InstanceField) o;
-
- if (!field.equals(that.field)) return false;
- if (!instance.equals(that.instance)) return false;
-
- return true;
+ return field.equals(that.field) && instance.equals(that.instance);
}
@Override
diff --git a/src/org/mockito/internal/util/reflection/Whitebox.java b/src/org/mockito/internal/util/reflection/Whitebox.java
index d1ba5fd..54a7cc6 100644
--- a/src/org/mockito/internal/util/reflection/Whitebox.java
+++ b/src/org/mockito/internal/util/reflection/Whitebox.java
@@ -1,7 +1,7 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.util.reflection;
import java.lang.reflect.Field;
@@ -15,7 +15,7 @@
f.setAccessible(true);
return f.get(target);
} catch (Exception e) {
- throw new RuntimeException("Unable to set internal state on a private field. Please report to mockito mailing list.", e);
+ throw new RuntimeException("Unable to get internal state on a private field. Please report to mockito mailing list.", e);
}
}
@@ -38,7 +38,7 @@
}
if (f == null) {
throw new RuntimeException(
- "You want me to set value to this field: '" + field +
+ "You want me to get this field: '" + field +
"' on this class: '" + clazz.getSimpleName() +
"' but this field is not declared withing hierarchy of this class!");
}
diff --git a/src/org/mockito/internal/verification/VerificationDataImpl.java b/src/org/mockito/internal/verification/VerificationDataImpl.java
index 74340c8..870820b 100644
--- a/src/org/mockito/internal/verification/VerificationDataImpl.java
+++ b/src/org/mockito/internal/verification/VerificationDataImpl.java
@@ -1,11 +1,9 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.internal.verification;
-import java.util.List;
-
import org.mockito.exceptions.Reporter;
import org.mockito.internal.invocation.InvocationMatcher;
import org.mockito.internal.stubbing.InvocationContainer;
@@ -13,6 +11,8 @@
import org.mockito.internal.verification.api.VerificationData;
import org.mockito.invocation.Invocation;
+import java.util.List;
+
public class VerificationDataImpl implements VerificationData {
private final InvocationMatcher wanted;
@@ -32,11 +32,11 @@
return wanted;
}
- void assertWantedIsVerifiable() {
+ private void assertWantedIsVerifiable() {
if (wanted == null) {
return;
}
- ObjectMethodsGuru o = new ObjectMethodsGuru();
+ ObjectMethodsGuru o = new ObjectMethodsGuru();
if (o.isToString(wanted.getMethod())) {
new Reporter().cannotVerifyToString();
}
diff --git a/src/org/mockito/internal/verification/VerificationOverTimeImpl.java b/src/org/mockito/internal/verification/VerificationOverTimeImpl.java
new file mode 100644
index 0000000..5c67348
--- /dev/null
+++ b/src/org/mockito/internal/verification/VerificationOverTimeImpl.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
+package org.mockito.internal.verification;
+
+import org.mockito.exceptions.base.MockitoAssertionError;
+import org.mockito.exceptions.verification.junit.ArgumentsAreDifferent;
+import org.mockito.internal.util.Timer;
+import org.mockito.internal.verification.api.VerificationData;
+import org.mockito.verification.VerificationMode;
+
+/**
+ * Verifies that another verification mode (the delegate) is satisfied within a certain timeframe
+ * (before timeoutMillis has passed, measured from the call to verify()), and either returns immediately
+ * once it does, or waits until it is definitely satisfied once the full time has passed.
+ */
+public class VerificationOverTimeImpl implements VerificationMode {
+
+ private final long pollingPeriodMillis;
+ private final long durationMillis;
+ private final VerificationMode delegate;
+ private final boolean returnOnSuccess;
+ private final Timer timer;
+
+ /**
+ * Create this verification mode, to be used to verify invocation ongoing data later.
+ *
+ * @param pollingPeriodMillis The frequency to poll delegate.verify(), to check whether the delegate has been satisfied
+ * @param durationMillis The max time to wait (in millis) for the delegate verification mode to be satisfied
+ * @param delegate The verification mode to delegate overall success or failure to
+ * @param returnOnSuccess Whether to immediately return successfully once the delegate is satisfied (as in
+ * {@link org.mockito.verification.VerificationWithTimeout}, or to only return once
+ * the delegate is satisfied and the full duration has passed (as in
+ * {@link org.mockito.verification.VerificationAfterDelay}).
+ */
+ public VerificationOverTimeImpl(long pollingPeriodMillis, long durationMillis, VerificationMode delegate, boolean returnOnSuccess) {
+ this.pollingPeriodMillis = pollingPeriodMillis;
+ this.durationMillis = durationMillis;
+ this.delegate = delegate;
+ this.returnOnSuccess = returnOnSuccess;
+ this.timer = new Timer(durationMillis);
+ }
+
+ /**
+ * Create this verification mode, to be used to verify invocation ongoing data later.
+ *
+ * @param pollingPeriodMillis The frequency to poll delegate.verify(), to check whether the delegate has been satisfied
+ * @param durationMillis The max time to wait (in millis) for the delegate verification mode to be satisfied
+ * @param delegate The verification mode to delegate overall success or failure to
+ * @param returnOnSuccess Whether to immediately return successfully once the delegate is satisfied (as in
+ * {@link org.mockito.verification.VerificationWithTimeout}, or to only return once
+ * the delegate is satisfied and the full duration has passed (as in
+ * {@link org.mockito.verification.VerificationAfterDelay}).
+ * @param timer Checker of whether the duration of the verification is still acceptable
+ */
+ public VerificationOverTimeImpl(long pollingPeriodMillis, long durationMillis, VerificationMode delegate, boolean returnOnSuccess, Timer timer) {
+ this.pollingPeriodMillis = pollingPeriodMillis;
+ this.durationMillis = durationMillis;
+ this.delegate = delegate;
+ this.returnOnSuccess = returnOnSuccess;
+ this.timer = timer;
+ }
+
+ /**
+ * Verify the given ongoing verification data, and confirm that it satisfies the delegate verification mode
+ * before the full duration has passed.
+ *
+ * In practice, this polls the delegate verification mode until it is satisfied. If it is not satisfied once
+ * the full duration has passed, the last error returned by the delegate verification mode will be thrown
+ * here in turn. This may be thrown early if the delegate is unsatisfied and the verification mode is known
+ * to never recover from this situation (e.g. {@link AtMost}).
+ *
+ * If it is satisfied before the full duration has passed, behaviour is dependent on the returnOnSuccess parameter
+ * given in the constructor. If true, this verification mode is immediately satisfied once the delegate is. If
+ * false, this verification mode is not satisfied until the delegate is satisfied and the full time has passed.
+ *
+ * @throws MockitoAssertionError if the delegate verification mode does not succeed before the timeout
+ */
+ public void verify(VerificationData data) {
+ AssertionError error = null;
+
+ timer.start();
+ while (timer.isCounting()) {
+ try {
+ delegate.verify(data);
+
+ if (returnOnSuccess) {
+ return;
+ } else {
+ error = null;
+ }
+ } catch (MockitoAssertionError e) {
+ error = handleVerifyException(e);
+ }
+ catch (ArgumentsAreDifferent e) {
+ error = handleVerifyException(e);
+ }
+ }
+
+ if (error != null) {
+ throw error;
+ }
+ }
+
+ private AssertionError handleVerifyException(AssertionError e) {
+ if (canRecoverFromFailure(delegate)) {
+ sleep(pollingPeriodMillis);
+ return e;
+ } else {
+ throw e;
+ }
+ }
+
+ protected boolean canRecoverFromFailure(VerificationMode verificationMode) {
+ return !(verificationMode instanceof AtMost || verificationMode instanceof NoMoreInteractions);
+ }
+
+ private void sleep(long sleep) {
+ try {
+ Thread.sleep(sleep);
+ } catch (InterruptedException ie) {
+ // oups. not much luck.
+ }
+ }
+
+ public long getPollingPeriod() {
+ return pollingPeriodMillis;
+ }
+
+ public long getDuration() {
+ return durationMillis;
+ }
+
+ public VerificationMode getDelegate() {
+ return delegate;
+ }
+
+}
diff --git a/src/org/mockito/internal/verification/VerificationWithTimeoutImpl.java b/src/org/mockito/internal/verification/VerificationWithTimeoutImpl.java
deleted file mode 100644
index 0e08005..0000000
--- a/src/org/mockito/internal/verification/VerificationWithTimeoutImpl.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
-package org.mockito.internal.verification;
-
-import org.mockito.exceptions.base.MockitoAssertionError;
-import org.mockito.internal.verification.api.VerificationData;
-import org.mockito.verification.VerificationMode;
-
-public class VerificationWithTimeoutImpl {
-
- VerificationMode delegate;
- int timeout;
- int treshhold;
-
- public VerificationWithTimeoutImpl(int treshhold, int millis, VerificationMode delegate) {
- this.treshhold = treshhold;
- this.timeout = millis;
- this.delegate = delegate;
- }
-
- public void verify(VerificationData data) {
- int soFar = 0;
- MockitoAssertionError error = null;
- while (soFar <= timeout) {
- try {
- delegate.verify(data);
- return;
- } catch (MockitoAssertionError e) {
- error = e;
- soFar += treshhold;
- sleep(treshhold);
- }
- }
- if (error != null) {
- throw error;
- }
- }
-
- void sleep(int sleep) {
- try {
- Thread.sleep(sleep);
- } catch (InterruptedException ie) {
- // oups. not much luck.
- }
- }
-
- public VerificationMode getDelegate() {
- return delegate;
- }
-
- public int getTimeout() {
- return timeout;
- }
-
- public int getTreshhold() {
- return treshhold;
- }
-}
\ No newline at end of file
diff --git a/src/org/mockito/invocation/DescribedInvocation.java b/src/org/mockito/invocation/DescribedInvocation.java
index bd8215c..b182235 100644
--- a/src/org/mockito/invocation/DescribedInvocation.java
+++ b/src/org/mockito/invocation/DescribedInvocation.java
@@ -5,12 +5,10 @@
package org.mockito.invocation;
import org.mockito.exceptions.PrintableInvocation;
-import org.mockito.Incubating;
/**
* Provides information about the invocation, specifically a human readable description and the location.
*/
-@Incubating
public interface DescribedInvocation extends PrintableInvocation {
/**
diff --git a/src/org/mockito/invocation/Invocation.java b/src/org/mockito/invocation/Invocation.java
index 34d53f6..0146697 100644
--- a/src/org/mockito/invocation/Invocation.java
+++ b/src/org/mockito/invocation/Invocation.java
@@ -4,8 +4,6 @@
*/
package org.mockito.invocation;
-import org.mockito.Incubating;
-
/**
* 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.
@@ -16,7 +14,6 @@
*
* @since 1.9.5
*/
-@Incubating
public interface Invocation extends InvocationOnMock, DescribedInvocation {
/**
diff --git a/src/org/mockito/invocation/InvocationOnMock.java b/src/org/mockito/invocation/InvocationOnMock.java
index 45d435a..815b8a4 100644
--- a/src/org/mockito/invocation/InvocationOnMock.java
+++ b/src/org/mockito/invocation/InvocationOnMock.java
@@ -35,6 +35,15 @@
* @return arguments
*/
Object[] getArguments();
+
+ /**
+ * Returns casted argument using position
+ * @param index argument position
+ * @param clazz argument type
+ * @return casted argument on position
+ */
+ <T> T getArgumentAt(int index, Class<T> clazz);
+
/**
* calls real method
diff --git a/src/org/mockito/invocation/Location.java b/src/org/mockito/invocation/Location.java
index 23def6a..e362704 100644
--- a/src/org/mockito/invocation/Location.java
+++ b/src/org/mockito/invocation/Location.java
@@ -4,12 +4,9 @@
*/
package org.mockito.invocation;
-import org.mockito.Incubating;
-
/**
* Describes the location of something in the source code.
*/
-@Incubating
public interface Location {
/**
diff --git a/src/org/mockito/invocation/MockHandler.java b/src/org/mockito/invocation/MockHandler.java
index 07f68f7..bf3aade 100644
--- a/src/org/mockito/invocation/MockHandler.java
+++ b/src/org/mockito/invocation/MockHandler.java
@@ -1,11 +1,9 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.invocation;
-import org.mockito.Incubating;
-
import java.io.Serializable;
/**
@@ -15,7 +13,6 @@
* This api is work in progress. Do not provide your own implementations.
* Mockito will provide you with the implementation via other {@link org.mockito.plugins.MockMaker} methods.
*/
-@Incubating
public interface MockHandler extends Serializable {
/**
* Takes an invocation object and handles it.
@@ -28,6 +25,5 @@
* @return Result
* @throws Throwable Throwable
*/
- @Incubating
Object handle(Invocation invocation) throws Throwable;
}
diff --git a/src/org/mockito/invocation/StubInfo.java b/src/org/mockito/invocation/StubInfo.java
index 0eb271f..6247336 100644
--- a/src/org/mockito/invocation/StubInfo.java
+++ b/src/org/mockito/invocation/StubInfo.java
@@ -4,12 +4,9 @@
*/
package org.mockito.invocation;
-import org.mockito.Incubating;
-
/**
* The information about stubbing, for example the location of stubbing.
*/
-@Incubating
public interface StubInfo {
/**
diff --git a/src/org/mockito/junit/MockitoJUnit.java b/src/org/mockito/junit/MockitoJUnit.java
new file mode 100644
index 0000000..f13b667
--- /dev/null
+++ b/src/org/mockito/junit/MockitoJUnit.java
@@ -0,0 +1,19 @@
+package org.mockito.junit;
+
+/**
+ * The JUnit rule can be used instead of {@link org.mockito.runners.MockitoJUnitRunner}. See {@link MockitoRule}.
+ *
+ * @since 1.10.17
+ */
+public class MockitoJUnit {
+
+ /**
+ * Creates rule instance that initiates @Mocks
+ * See {@link MockitoRule}.
+ *
+ * @return the rule instance
+ */
+ public static MockitoRule rule() {
+ return new MockitoJUnitRule();
+ }
+}
diff --git a/src/org/mockito/junit/MockitoJUnitRule.java b/src/org/mockito/junit/MockitoJUnitRule.java
new file mode 100644
index 0000000..7e53273
--- /dev/null
+++ b/src/org/mockito/junit/MockitoJUnitRule.java
@@ -0,0 +1,42 @@
+package org.mockito.junit;
+
+import org.junit.rules.MethodRule;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.Statement;
+import org.mockito.internal.junit.JUnitRule;
+
+
+/**
+ * Please use {@link MockitoJUnit#rule()} instead of direct use.
+ * The reason of the deprecation is that we want to avoid concrete classes in the public api.
+ *
+ * @see MockitoJUnit
+ * @since 1.10.6
+ */
+@Deprecated
+public class MockitoJUnitRule implements MethodRule, MockitoRule {
+ //MethodRule is undeprecated in latest JUnit
+ private final JUnitRule jUnitRule;
+
+ /**
+ * Please use {@link MockitoJUnit#rule()}.
+ * The reason of the deprecation is that we want to avoid concrete classes in the public api.
+ */
+ @Deprecated
+ public MockitoJUnitRule() {
+ this.jUnitRule = new JUnitRule();
+ }
+
+ /**
+ * Please use {@link MockitoJUnit#rule()}.
+ * The reason of the deprecation is that we want to avoid concrete classes in the public api.
+ */
+ @Deprecated
+ public MockitoJUnitRule(Object targetTest) {
+ this();
+ }
+
+ public Statement apply(Statement base, FrameworkMethod method, Object target) {
+ return jUnitRule.apply(base, target);
+ }
+}
diff --git a/src/org/mockito/junit/MockitoRule.java b/src/org/mockito/junit/MockitoRule.java
new file mode 100644
index 0000000..1778ed6
--- /dev/null
+++ b/src/org/mockito/junit/MockitoRule.java
@@ -0,0 +1,37 @@
+package org.mockito.junit;
+
+import org.junit.rules.MethodRule;
+
+/**
+ * The JUnit rule can be used instead of {@link org.mockito.runners.MockitoJUnitRunner}.
+ * It requires JUnit at least 4.7.
+ *
+ * This rule adds following behavior:
+ * <ul>
+ * <li>
+ * Initializes mocks annotated with {@link org.mockito.Mock},
+ * so that explicit usage of {@link org.mockito.MockitoAnnotations#initMocks(Object)} is not necessary.
+ * Mocks are initialized before each test method.
+ * <li>
+ * validates framework usage after each test method. See javadoc for {@link org.mockito.Mockito#validateMockitoUsage()}.
+ * </ul>
+ * Example use:
+ * <pre class="code"><code class="java">
+ * public class ExampleTest {
+ *
+ * @Rule
+ * public MockitoRule rule = MockitoJUnit.rule();
+ *
+ * @Mock
+ * private List list;
+ *
+ * @Test
+ * public void shouldDoSomething() {
+ * list.add(100);
+ * }
+ * }
+ * </code></pre>
+ *
+ * @since 1.10.17
+ */
+public interface MockitoRule extends MethodRule {}
diff --git a/src/org/mockito/mock/MockCreationSettings.java b/src/org/mockito/mock/MockCreationSettings.java
index 8f561a0..6b91a47 100644
--- a/src/org/mockito/mock/MockCreationSettings.java
+++ b/src/org/mockito/mock/MockCreationSettings.java
@@ -15,7 +15,6 @@
/**
* Informs about the mock settings. An immutable view of {@link org.mockito.MockSettings}.
*/
-@Incubating
public interface MockCreationSettings<T> {
/**
@@ -49,6 +48,11 @@
boolean isSerializable();
/**
+ * @return the serializable mode of this mock
+ */
+ SerializableMode getSerializableMode();
+
+ /**
* Whether the mock is only for stubbing, i.e. does not remember
* parameters on its invocation and therefore cannot
* be used for verification
@@ -56,7 +60,24 @@
boolean isStubOnly();
/**
- * the invocation listeners attached to this mock, see {@link org.mockito.MockSettings#invocationListeners}.
+ * The invocation listeners attached to this mock, see {@link org.mockito.MockSettings#invocationListeners}.
*/
List<InvocationListener> getInvocationListeners();
+
+ /**
+ * Informs whether the mock instance should be created via constructor
+ *
+ * @since 1.10.12
+ */
+ @Incubating
+ boolean isUsingConstructor();
+
+ /**
+ * Used when mocking non-static inner classes in conjunction with {@link #isUsingConstructor()}
+ *
+ * @return the outer class instance used for creation of the mock object via the constructor.
+ * @since 1.10.12
+ */
+ @Incubating
+ Object getOuterClassInstance();
}
\ No newline at end of file
diff --git a/src/org/mockito/mock/SerializableMode.java b/src/org/mockito/mock/SerializableMode.java
new file mode 100644
index 0000000..d10b1d6
--- /dev/null
+++ b/src/org/mockito/mock/SerializableMode.java
@@ -0,0 +1,26 @@
+package org.mockito.mock;
+
+import org.mockito.Incubating;
+
+/**
+ * Mock serializable style.
+ */
+@Incubating
+public enum SerializableMode {
+
+ /**
+ * No serialization.
+ */
+ NONE,
+
+ /**
+ * Basic serializable mode for mock objects. Introduced in Mockito 1.8.1.
+ */
+ BASIC,
+
+ /**
+ * Useful if the mock is deserialized in a different classloader / vm.
+ */
+ @Incubating
+ ACROSS_CLASSLOADERS
+}
\ No newline at end of file
diff --git a/src/org/mockito/plugins/MockMaker.java b/src/org/mockito/plugins/MockMaker.java
index c97dfb5..242c273 100644
--- a/src/org/mockito/plugins/MockMaker.java
+++ b/src/org/mockito/plugins/MockMaker.java
@@ -4,7 +4,6 @@
*/
package org.mockito.plugins;
-import org.mockito.Incubating;
import org.mockito.invocation.MockHandler;
import org.mockito.mock.MockCreationSettings;
@@ -35,7 +34,6 @@
* @see org.mockito.invocation.MockHandler
* @since 1.9.5
*/
-@Incubating
public interface MockMaker {
/**
diff --git a/src/org/mockito/plugins/PluginSwitch.java b/src/org/mockito/plugins/PluginSwitch.java
new file mode 100644
index 0000000..4c08974
--- /dev/null
+++ b/src/org/mockito/plugins/PluginSwitch.java
@@ -0,0 +1,24 @@
+package org.mockito.plugins;
+
+import org.mockito.Incubating;
+
+/**
+ * Allows switching off the plugins that are discovered on classpath.
+ * When a particular plugin is switched off, the default Mockito behavior is used.
+ * For example, if Android's dexmaker MockMaker is switched off,
+ * Mockito default MockMaker implementation is used {@link org.mockito.plugins.MockMaker}
+ *
+ * @since 1.10.15
+ */
+@Incubating
+public interface PluginSwitch {
+
+ /**
+ * Mockito invokes this method for every plugin found in the classpath
+ * (except from the {@code PluginSwitch} implementation itself).
+ * If no custom plugins are discovered this method is not invoked.
+ *
+ * @since 1.10.15
+ */
+ boolean isEnabled(String pluginClassName);
+}
\ No newline at end of file
diff --git a/src/org/mockito/plugins/StackTraceCleanerProvider.java b/src/org/mockito/plugins/StackTraceCleanerProvider.java
index ee0f998..1671795 100644
--- a/src/org/mockito/plugins/StackTraceCleanerProvider.java
+++ b/src/org/mockito/plugins/StackTraceCleanerProvider.java
@@ -1,6 +1,5 @@
package org.mockito.plugins;
-import org.mockito.Incubating;
import org.mockito.exceptions.stacktrace.StackTraceCleaner;
/**
@@ -9,13 +8,10 @@
* You can also 'enhance' Mockito's default behavior
* because the default cleaner is passed as parameter to the method.
* <p>
- * For more information how to register custom StackTraceCleaner
- * please refer to the documentation of {@link MockMaker}.
- * We will update the documentation shortly.
+ * Registering custom StackTraceCleaner is done in similar manner as the {@link MockMaker} implementation.
* <p>
* See the default implementation: {@link org.mockito.internal.exceptions.stacktrace.DefaultStackTraceCleanerProvider}
*/
-@Incubating
public interface StackTraceCleanerProvider {
/**
diff --git a/src/org/mockito/plugins/package.html b/src/org/mockito/plugins/package.html
new file mode 100644
index 0000000..72e0d04
--- /dev/null
+++ b/src/org/mockito/plugins/package.html
@@ -0,0 +1,10 @@
+<!--
+ ~ Copyright (c) 2007 Mockito contributors
+ ~ This program is made available under the terms of the MIT License.
+ -->
+
+<body>
+Mockito plugins allow customization of behavior.
+For example, it is useful for Android integration via dexmaker.
+See examples in docs for MockMaker.
+</body>
diff --git a/src/org/mockito/runners/ConsoleSpammingMockitoJUnitRunner.java b/src/org/mockito/runners/ConsoleSpammingMockitoJUnitRunner.java
index 637f932..2dfdab0 100644
--- a/src/org/mockito/runners/ConsoleSpammingMockitoJUnitRunner.java
+++ b/src/org/mockito/runners/ConsoleSpammingMockitoJUnitRunner.java
@@ -1,11 +1,9 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.runners;
-import java.lang.reflect.InvocationTargetException;
-
import org.junit.runner.Description;
import org.junit.runner.Runner;
import org.junit.runner.manipulation.Filter;
@@ -21,6 +19,8 @@
import org.mockito.internal.util.ConsoleMockitoLogger;
import org.mockito.internal.util.MockitoLogger;
+import java.lang.reflect.InvocationTargetException;
+
/**
* Uses <b>JUnit 4.5</b> runner {@link BlockJUnit4ClassRunner}.
* <p>
@@ -89,7 +89,7 @@
public class ConsoleSpammingMockitoJUnitRunner extends Runner implements Filterable {
private final MockitoLogger logger;
- private RunnerImpl runner;
+ private final RunnerImpl runner;
public ConsoleSpammingMockitoJUnitRunner(Class<?> klass) throws InvocationTargetException {
this(new ConsoleMockitoLogger(), new RunnerFactory().create(klass));
diff --git a/src/org/mockito/runners/VerboseMockitoJUnitRunner.java b/src/org/mockito/runners/VerboseMockitoJUnitRunner.java
index d98d831..a0f71c9 100644
--- a/src/org/mockito/runners/VerboseMockitoJUnitRunner.java
+++ b/src/org/mockito/runners/VerboseMockitoJUnitRunner.java
@@ -1,11 +1,9 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.runners;
-import java.lang.reflect.InvocationTargetException;
-
import org.junit.runner.Description;
import org.junit.runner.Runner;
import org.junit.runner.manipulation.Filter;
@@ -19,6 +17,8 @@
import org.mockito.internal.runners.RunnerImpl;
import org.mockito.internal.util.junit.JUnitFailureHacker;
+import java.lang.reflect.InvocationTargetException;
+
/**
* Experimental implementation that suppose to improve tdd/testing experience.
* Don't hesitate to send feedback to mockito@googlegroups.com
@@ -28,7 +28,7 @@
* adds extra Mocktio hints to the exception message.
* The point is that Mockito should help the tdd developer to quickly figure out if the test fails for the right reason and track the reason.
* <p>
- * The implemntation is pretty hacky - it uses brute force of reflection to modify the exception message and add extra mockito hints.
+ * The implementation is pretty hacky - it uses brute force of reflection to modify the exception message and add extra mockito hints.
* You've been warned.
* <p>
* Do you think it is useful or not? Drop us an email at mockito@googlegroups.com
@@ -37,7 +37,7 @@
*/
public class VerboseMockitoJUnitRunner extends Runner implements Filterable {
- private RunnerImpl runner;
+ private final RunnerImpl runner;
public VerboseMockitoJUnitRunner(Class<?> klass) throws InvocationTargetException {
this(new RunnerFactory().create(klass));
diff --git a/src/org/mockito/stubbing/Answer.java b/src/org/mockito/stubbing/Answer.java
index 784a268..997d69d 100644
--- a/src/org/mockito/stubbing/Answer.java
+++ b/src/org/mockito/stubbing/Answer.java
@@ -17,11 +17,11 @@
* Object answer(InvocationOnMock invocation) {
* Object[] args = invocation.getArguments();
* Object mock = invocation.getMock();
- * return "called with arguments: " + args;
+ * return "called with arguments: " + Arrays.toString(args);
* }
* });
*
- * //Following prints "called with arguments: foo"
+ * //Following prints "called with arguments: [foo]"
* System.out.println(mock.someMethod("foo"));
* </code></pre>
*
diff --git a/src/org/mockito/verification/After.java b/src/org/mockito/verification/After.java
new file mode 100644
index 0000000..07d3122
--- /dev/null
+++ b/src/org/mockito/verification/After.java
@@ -0,0 +1,32 @@
+package org.mockito.verification;
+
+import org.mockito.internal.verification.VerificationOverTimeImpl;
+
+/**
+ * See the javadoc for {@link VerificationAfterDelay}
+ * <p>
+ * Typically, you won't use this class explicitly. Instead use timeout() method on Mockito class.
+ * See javadoc for {@link VerificationWithTimeout}
+ */
+public class After extends VerificationWrapper<VerificationOverTimeImpl> implements VerificationAfterDelay {
+
+ /**
+ * See the javadoc for {@link VerificationAfterDelay}
+ * <p>
+ * Typically, you won't use this class explicitly. Instead use timeout() method on Mockito class.
+ * See javadoc for {@link VerificationWithTimeout}
+ */
+ public After(long delayMillis, VerificationMode verificationMode) {
+ this(10, delayMillis, verificationMode);
+ }
+
+ public After(long pollingPeriod, long delayMillis, VerificationMode verificationMode) {
+ super(new VerificationOverTimeImpl(pollingPeriod, delayMillis, verificationMode, false));
+ }
+
+ @Override
+ protected VerificationMode copySelfWithNewVerificationMode(VerificationMode verificationMode) {
+ return new After(wrappedVerification.getPollingPeriod(), wrappedVerification.getDuration(), verificationMode);
+ }
+
+}
diff --git a/src/org/mockito/verification/Timeout.java b/src/org/mockito/verification/Timeout.java
index e120622..d8e87ba 100644
--- a/src/org/mockito/verification/Timeout.java
+++ b/src/org/mockito/verification/Timeout.java
@@ -1,89 +1,57 @@
-/*
- * Copyright (c) 2007 Mockito contributors
- * This program is made available under the terms of the MIT License.
- */
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
package org.mockito.verification;
import org.mockito.exceptions.Reporter;
-import org.mockito.exceptions.misusing.FriendlyReminderException;
-import org.mockito.internal.verification.VerificationModeFactory;
-import org.mockito.internal.verification.VerificationWithTimeoutImpl;
-import org.mockito.internal.verification.api.VerificationData;
-
+import org.mockito.internal.util.Timer;
+import org.mockito.internal.verification.VerificationOverTimeImpl;
/**
* See the javadoc for {@link VerificationWithTimeout}
* <p>
* Typically, you won't use this class explicitly. Instead use timeout() method on Mockito class.
* See javadoc for {@link VerificationWithTimeout}
*/
-public class Timeout implements VerificationWithTimeout {
-
- VerificationWithTimeoutImpl impl;
-
+public class Timeout extends VerificationWrapper<VerificationOverTimeImpl> implements VerificationWithTimeout {
+
/**
* See the javadoc for {@link VerificationWithTimeout}
* <p>
* Typically, you won't use this class explicitly. Instead use timeout() method on Mockito class.
* See javadoc for {@link VerificationWithTimeout}
*/
- public Timeout(int millis, VerificationMode delegate) {
+ public Timeout(long millis, VerificationMode delegate) {
this(10, millis, delegate);
}
/**
* See the javadoc for {@link VerificationWithTimeout}
*/
- Timeout(int treshhold, int millis, VerificationMode delegate) {
- this.impl = new VerificationWithTimeoutImpl(treshhold, millis, delegate);
+ Timeout(long pollingPeriodMillis, long millis, VerificationMode delegate) {
+ super(new VerificationOverTimeImpl(pollingPeriodMillis, millis, delegate, true));
}
/**
* See the javadoc for {@link VerificationWithTimeout}
*/
- public void verify(VerificationData data) {
- impl.verify(data);
+ Timeout(long pollingPeriodMillis, long millis, VerificationMode delegate, Timer timer) {
+ super(new VerificationOverTimeImpl(pollingPeriodMillis, millis, delegate, true, timer));
}
-
- /**
- * See the javadoc for {@link VerificationWithTimeout}
- */
- public VerificationMode atLeast(int minNumberOfInvocations) {
- return new Timeout(impl.getTreshhold(), impl.getTimeout(), VerificationModeFactory.atLeast(minNumberOfInvocations));
+
+ @Override
+ protected VerificationMode copySelfWithNewVerificationMode(VerificationMode newVerificationMode) {
+ return new Timeout(wrappedVerification.getPollingPeriod(), wrappedVerification.getDuration(), newVerificationMode);
}
-
- /**
- * See the javadoc for {@link VerificationWithTimeout}
- */
- public VerificationMode atLeastOnce() {
- return new Timeout(impl.getTreshhold(), impl.getTimeout(), VerificationModeFactory.atLeastOnce());
- }
-
- /**
- * See the javadoc for {@link VerificationWithTimeout}
- */
+
public VerificationMode atMost(int maxNumberOfInvocations) {
- new Reporter().atMostShouldNotBeUsedWithTimeout();
+ new Reporter().atMostAndNeverShouldNotBeUsedWithTimeout();
return null;
}
- /**
- * See the javadoc for {@link VerificationWithTimeout}
- */
public VerificationMode never() {
- return new Timeout(impl.getTreshhold(), impl.getTimeout(), VerificationModeFactory.times(0));
+ new Reporter().atMostAndNeverShouldNotBeUsedWithTimeout();
+ return null;
}
- /**
- * See the javadoc for {@link VerificationWithTimeout}
- */
- public VerificationMode only() {
- return new Timeout(impl.getTreshhold(), impl.getTimeout(), VerificationModeFactory.only());
- }
-
- /**
- * See the javadoc for {@link VerificationWithTimeout}
- */
- public VerificationMode times(int wantedNumberOfInvocations) {
- return new Timeout(impl.getTreshhold(), impl.getTimeout(), VerificationModeFactory.times(wantedNumberOfInvocations));
- }
}
\ No newline at end of file
diff --git a/src/org/mockito/verification/VerificationAfterDelay.java b/src/org/mockito/verification/VerificationAfterDelay.java
new file mode 100644
index 0000000..0df0f05
--- /dev/null
+++ b/src/org/mockito/verification/VerificationAfterDelay.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2007 Mockito contributors
+ * This program is made available under the terms of the MIT License.
+ */
+
+package org.mockito.verification;
+
+import org.mockito.Mockito;
+
+
+/**
+ * VerificationAfterDelay is a {@link VerificationMode} that allows combining existing verification modes with an initial delay, e.g.
+ * <pre class="code"><code class="java">
+ * verify(mock, after(100).atMost(5)).foo();
+ *
+ * verify(mock, after(100).never()).bar();
+ *
+ * verify(mock, after(200).atLeastOnce()).baz();
+ * </code></pre>
+ *
+ * This is similar to {@link VerificationWithTimeout timeout()} except the assertion will not terminate until either the condition is
+ * definitively failed, or the full time has elapsed (whereas timeout() will also stop if the conditions is true at any point, as is
+ * typically the case with never() etc initially).
+ *
+ * <p>
+ * See examples in javadoc for {@link Mockito#verify(Object, VerificationMode)}
+ *
+ */
+public interface VerificationAfterDelay extends VerificationMode {
+
+ /**
+ * Verifies that there are exactly N invocations during the given period. This will wait the full period given.
+ */
+ public VerificationMode times(int wantedNumberOfInvocations);
+
+ /**
+ * Allows verification that there are no invocations at any point during the given period. This will wait the
+ * full period given, unless an invocation occurs (in which case there will be immediate failure)
+ */
+ public VerificationMode never();
+
+ /**
+ * Verifies that there is at least 1 invocation during the given period. This will wait the full period given.
+ */
+ public VerificationMode atLeastOnce();
+
+ /**
+ * Verifies that there is are least N invocations during the given period. This will wait the full period given.
+ */
+ public VerificationMode atLeast(int minNumberOfInvocations);
+
+ /**
+ * Verifies that there is are most N invocations during the given period. This will wait the full period given,
+ * unless too many invocations occur (in which case there will be an immediate failure)
+ */
+ public VerificationMode atMost(int maxNumberOfInvocations);
+
+ /**
+ * Verifies that there the given method is invoked and is the only method invoked. This will wait the full
+ * period given, unless another method is invoked (in which case there will be an immediate failure)
+ */
+ public VerificationMode only();
+
+}
diff --git a/src/org/mockito/verification/VerificationWithTimeout.java b/src/org/mockito/verification/VerificationWithTimeout.java
index 0b4c923..2e54933 100644
--- a/src/org/mockito/verification/VerificationWithTimeout.java
+++ b/src/org/mockito/verification/VerificationWithTimeout.java
@@ -18,6 +18,10 @@
* verify(mock, timeout(200).atLeastOnce()).baz();
* </code></pre>
*
+ * This is similar to {@link VerificationAfterDelay after()} except this assertion will immediately pass if it becomes true at any point,
+ * whereas after() will wait the full period. Assertions which are consistently expected to be initially true and potentially become false
+ * are deprecated below, and after() should be used instead.
+ *
* <p>
* See examples in javadoc for {@link Mockito#verify(Object, VerificationMode)}
*/
@@ -38,25 +42,23 @@
public VerificationMode times(int wantedNumberOfInvocations);
/**
- * Alias to times(0), see {@link #times(int)}
+ * @deprecated
+ * Validation with timeout combined with never simply does not make sense, as never() will typically immediately pass,
+ * and therefore not wait the timeout. The behaviour you may be looking for is actually provided by after().never().
* <p>
- * Verifies that interaction did not happen within given timeout. E.g:
- * <pre class="code"><code class="java">
- * verify(mock, timeout(100).never()).someMethod();
- * </code></pre>
- *
+ * To avoid compilation errors upon upgrade the method is deprecated and it throws a "friendly reminder" exception.
* <p>
- * If you want to verify there were NO interactions with the mock
- * check out {@link Mockito#verifyNoMoreInteractions(Object...)}
+ * In a future release we will remove timeout(x).atMost(y) and timeout(x).never() from the API.
* <p>
- * See examples in javadoc for {@link Mockito} class
+ * Do you want to find out more? See <a href="http://code.google.com/p/mockito/issues/detail?id=235">issue 235</a>
*
* @return verification mode
*/
+ @Deprecated
public VerificationMode never();
/**
- * Allows at-least-once verification withing given timeout. E.g:
+ * Allows at-least-once verification within given timeout. E.g:
* <pre class="code"><code class="java">
* verify(mock, timeout(100).atLeastOnce()).someMethod("some arg");
* </code></pre>
@@ -69,7 +71,7 @@
public VerificationMode atLeastOnce();
/**
- * Allows at-least-x verification withing given timeout. E.g:
+ * Allows at-least-x verification within given timeout. E.g:
* <pre class="code"><code class="java">
* verify(mock, timeout(100).atLeast(3)).someMethod("some arg");
* </code></pre>
@@ -86,12 +88,12 @@
* @deprecated
*
* <b>Deprecated</b>
- * validation with timeout combined with atMost simply does not make sense...
- * The test would have passed immediately in the concurrent environment
+ * Validation with timeout combined with never simply does not make sense, as atMost() will typically immediately pass,
+ * and therefore not wait the timeout. The behaviour you may be looking for is actually provided by after().atMost().
* <p>
- * To avoid compilation erros upon upgrade the method is deprecated and it throws a "friendly reminder" exception.
+ * To avoid compilation errors upon upgrade the method is deprecated and it throws a "friendly reminder" exception.
* <p>
- * In future release we will remove timeout(x).atMost(y) from the API.
+ * In a future release we will remove timeout(x).atMost(y) and timeout(x).never() from the API.
* <p>
* Do you want to find out more? See <a href="http://code.google.com/p/mockito/issues/detail?id=235">issue 235</a>
*
diff --git a/src/org/mockito/verification/VerificationWrapper.java b/src/org/mockito/verification/VerificationWrapper.java
new file mode 100644
index 0000000..d32fab2
--- /dev/null
+++ b/src/org/mockito/verification/VerificationWrapper.java
@@ -0,0 +1,44 @@
+package org.mockito.verification;
+
+import org.mockito.internal.verification.VerificationModeFactory;
+import org.mockito.internal.verification.api.VerificationData;
+
+public abstract class VerificationWrapper<WrapperType extends VerificationMode> implements VerificationMode {
+
+ protected final WrapperType wrappedVerification;
+
+ public VerificationWrapper(WrapperType wrappedVerification) {
+ this.wrappedVerification = wrappedVerification;
+ }
+
+ public void verify(VerificationData data) {
+ wrappedVerification.verify(data);
+ }
+
+ protected abstract VerificationMode copySelfWithNewVerificationMode(VerificationMode verificationMode);
+
+ public VerificationMode times(int wantedNumberOfInvocations) {
+ return copySelfWithNewVerificationMode(VerificationModeFactory.times(wantedNumberOfInvocations));
+ }
+
+ public VerificationMode never() {
+ return copySelfWithNewVerificationMode(VerificationModeFactory.atMost(0));
+ }
+
+ public VerificationMode atLeastOnce() {
+ return copySelfWithNewVerificationMode(VerificationModeFactory.atLeastOnce());
+ }
+
+ public VerificationMode atLeast(int minNumberOfInvocations) {
+ return copySelfWithNewVerificationMode(VerificationModeFactory.atLeast(minNumberOfInvocations));
+ }
+
+ public VerificationMode atMost(int maxNumberOfInvocations) {
+ return copySelfWithNewVerificationMode(VerificationModeFactory.atMost(maxNumberOfInvocations));
+ }
+
+ public VerificationMode only() {
+ return copySelfWithNewVerificationMode(VerificationModeFactory.only());
+ }
+
+}
diff --git a/update_source.sh b/update_source.sh
index 2f0d802..c4d3e39 100755
--- a/update_source.sh
+++ b/update_source.sh
@@ -5,6 +5,8 @@
# Retrieves the current Mockito source code into the current directory, excluding portions related
# to mockito's internal build system and javadoc.
+VERSION=${1-master}
+
SOURCE="git://github.com/mockito/mockito.git"
INCLUDE="
LICENSE
@@ -25,6 +27,7 @@
echo "Fetching Mockito source into $working_dir"
git clone $SOURCE $working_dir/source
+(cd $working_dir/source; git checkout $VERSION)
for include in ${INCLUDE}; do
echo "Updating $include"