Mockito matchers are static methods and calls to those methods that support arguments during calls when and verify .
Hamcrest connectors (archived version) (or Hamcrest-style matches) are generic objects that implement Matcher<T> and expose the matches(T) method, which returns true if the object matches the Matcher criteria. They are intended to be free from side effects and are commonly used in statements like the ones below.
verify(foo).setPowerLevel(gt(9000)); assertThat(foo.getPowerLevel(), is(greaterThan(9000)));
Mockito compositions exist separately from Hamcrest style templates, so descriptions of matching expressions directly fit into method calls: Mockito matchers return T , where Hamcrest matching methods return Matcher objects (such as Matcher<T> ).
Mockito connectors are invoked by static methods such as eq , any , gt and startsWith on org.mockito.Matchers and org.mockito.AdditionalMatchers . There are also adapters that have changed in versions of Mockito:
- For Mockito 1.x,
Matchers some calls are used (for example, intThat or argThat ), which are Mockito layouts that directly accept Hamcrest parameters as parameters. ArgumentMatcher<T> extended org.hamcrest.Matcher<T> , which was used in the internal representation of Hamcrest and was the base class of the Matrix for Hamcrest instead of any type of Mockito-pairing. - For Mockito 2.0+, Mockito is no longer directly dependent on Hamcrest.
Matchers , expressed as intThat or argThat wrap ArgumentMatcher<T> objects that no longer implement org.hamcrest.Matcher<T> but are used in the same way, Hamcrest adapters such as argThat and intThat are still available, but instead moved at MockitoHamcrest .
Whether the templates are Hamcrest or just a Hamcrest style, they can be adapted like this:
verify(foo).setPowerLevel(intThat(is(greaterThan(9000))));
In the above statement: foo.setPowerLevel is a method that accepts an int . is(greaterThan(9000)) returns a Matcher<Integer> , which will not work as the argument to setPowerLevel . The Mockito intThat intThat completes the Hamcrest-style match and returns an int , so it can be displayed as an argument; Mockito sockets, such as gt(9000) , carry this whole expression into one call, as in the first line of the sample code.
What sockets do / return
when(foo.quux(3, 5)).thenReturn(true);
When no arguments are used, Mockito writes your argument values ββand compares them with their equals methods.
when(foo.quux(eq(3), eq(5))).thenReturn(true); // same as above when(foo.quux(anyInt(), gt(5))).thenReturn(true); // this one different
When you call the corresponding element of type any or gt (more than), Mockito stores a conjugate object, due to which Mockito skips the equality check and applies your choice. In the case of argumentCaptor.capture() it saves a match, which saves its argument instead for later control.
Matches return dummy values , such as zero, empty collections, or null . Mockito is trying to return a safe, corresponding dummy value, for example 0 for anyInt() or any(Integer.class) or an empty List<String> for anyListOf(String.class) . However, due to the erasing of styles, Mockito does not have type information to return any value, but null for any() or argThat(...) , which can throw a NullPointerException when trying to "auto-unbox" a null primitive value.
Approaches, such as eq and gt , take parameter values; ideally, these values ββshould be calculated before starting / checking. A layout call in the middle of mocking another call may interfere with stubbing.
Matching methods cannot be used as return values; for example, there is no way to phrase thenReturn(anyInt()) or thenReturn(any(Foo.class)) in Mockito. Mockito must know exactly which instance will be returned when stubbing is called, and will not select an arbitrary return value for you.
Implementation Details
Matches are stored (as matches of objects of type Hamcrest) on the stack contained in the ArgumentMatcherStorage class. MockitoCore and Matchers have their own instance of ThreadSafeMockingProgress , which statically contains MockingProgress instances that support ThreadLocal. This is a MockingProgressImpl that contains a specific ArgumentMatcherStorageImpl.Therefore , the state of mock and matcher is static, but thread-dependent between the Mockito and Matchers classes.
Most answering calls are only added to this stack with an exception for items such as and , or and not . This perfectly matches (and relies on) the Java evaluation order , which evaluates the arguments from left to right before calling the method:
when(foo.quux(anyInt(), and(gt(10), lt(20)))).thenReturn(true); [6] [5] [1] [4] [2] [3]
This will:
- Add
anyInt() to the stack. - Add
gt(10) to the stack. - Add
lt(20) to the stack. - Remove
gt(10) and lt(20) and add and(gt(10), lt(20)) . - A call to
foo.quux(0, 0) , which (unless otherwise specified) returns the default value false . Internally Mockito marks quux(int, int) as the most recent call. - A
when(false) call that discards its argument and prepares the stub quux(int, int) method identified in 5. Only two valid states have a stack length of 0 (equality) or 2 (matches), and on the stack (steps 1 and 4 ), so Mockito chokes the method with any() for its first argument and and(gt(10), lt(20)) for its second argument and clears the stack.
This demonstrates a few rules:
Mockito cannot tell the difference between quux(anyInt(), 0) and quux(0, anyInt()) . Both of them look like a call to quux(0, 0) with one matching int on the stack. Therefore, if you use single matches, you must match all the arguments.
Ordering calls is not just important, it is what makes it all work. Highlighting templates for variables usually does not work, since it usually changes the order of the call. However, extracting sockets to methods works fine.
int between10And20 = and(gt(10), lt(20)); /* BAD */ when(foo.quux(anyInt(), between10And20)).thenReturn(true); // Mockito sees the stack as the opposite: and(gt(10), lt(20)), anyInt(). public static int anyIntBetween10And20() { return and(gt(10), lt(20)); } /* OK */ when(foo.quux(anyInt(), anyIntBetween10And20())).thenReturn(true); // The helper method calls the matcher methods in the right order.
The stack changes quite often, and Mockito cannot handle it carefully. It can only check the stack when you interact with a Mockito or layout, and must accept consonants without knowing if they are being used immediately or accidentally deleted. Theoretically, the stack should always be empty outside of the when or verify , but Mockito cannot check this automatically. You can check manually with Mockito.validateMockitoUsage() .
When calling when Mockito actually calls the method in question, which will throw an exception if you run the method to throw an exception (or require non-zero or non-zero values), doReturn and doAnswer (etc.) do not refer to the actual method and are often a useful alternative.
If you called the mock method in the middle of stubbing (for example, to calculate the response for an eq server), Mockito would check the stack length for this call and most likely would fail.
If you try to do something bad, such as the stubbing / verifying final method , Mockito will call the real method, and additional sockets on the stack will also go away. A final method call cannot throw an exception, but you can get an InvalidUseOfMatchersException from stray matches when you then interact with the layout.
Common problems
InvalidUseOfMatchersException :
Make sure that every single argument has exactly one conjugation call, if you use matches at all, and that you did not use the match outside of the when or verify . Matches should never be used as in-depth return values ββor fields / variables.
Make sure you do not invoke the layout as part of providing the mate argument.
Make sure you are not trying to stub / check the final method using the connector. This is a great way to leave the helper on the stack, and if your last method does not throw an exception, this may be the only time you realize that the method you are mocking is final.
NullPointerException with primitive arguments: (Integer) any() returns null, and any(Integer.class) returns 0; this can lead to a NullPointerException if you expect an int instead of an Integer. In any case, prefer anyInt() , which will return zero, as well as skip the automatic boxing step.
NullPointerException or other exceptions: Calls when(foo.bar(any())).thenReturn(baz) will actually call foo.bar(null) , which may throw an exception when it receives a null argument. Switching to doReturn(baz).when(foo).bar(any()) skips wired behavior .
General troubleshooting
Use MockitoJUnitRunner or explicitly call validateMockitoUsage in your tearDown or @After (which the runner will do for you automatically). This will help determine if you have used the sockets incorrectly.
For debugging purposes, add validateMockitoUsage calls directly to your code. This will happen if you have anything on the stack that is a good warning of a bad symptom.