Mockito Verification
This article is part of our Academy Course titled Testing with Mockito.
In this course, you will dive into the magic of Mockito. You will learn about Mocks, Spies and Partial Mocks, and their corresponding Stubbing behaviour. You will also see the process of Verification with Test Doubles and Object Matchers. Finally, Test Driven Development (TDD) with Mockito is discussed in order to see how this library fits in the concept of TDD. Check it out here!
Table Of Contents
1. What is Verification?
Verification is the process of confirming the behaviour of a Mock. It is useful in determining that the class we are testing has interacted in an expected way with any of its dependencies. Sometimes we aren’t interested in the values which are returned from a Mock, but are instead interested in how the class under test interacted with it, what values were sent in or how often it was called. The process of confirming this behaviour is verification and there are a number of tools which Mockito provides to allow us to do it.
2. Using verify()
The main tool for performing verification in the Mockito toolbox is the org.mockito.Mockito.verify()
method. The verify method takes the Mock object as a parameter and returns an instance of the same Class as the Mock, allowing you to call the methods of the Class, which Mockito interprets as a request to verify that there was some interaction with that method.
Let’s look again at our printer interface from the previous tutorial.
1 2 3 4 5 | public interface Printer { void printTestPage(); } |
We can create a simple unit test to demonstrate verify using a Mock Printer
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | import static org.mockito.Mockito.verify; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; @RunWith (MockitoJUnitRunner. class ) public class PrinterTest { @Mock private Printer printer; @Test public void simple_interaction_verification() { // Given // When printer.printTestPage(); // Then verify(printer).printTestPage(); } } |
We can see that our unit test firstly calls printer.printTestPage()
. This is simulating a possible interaction within a class under test, but to keep things simple we are doing it out in the unit test class. The next call is the call to verify(printer).printTestPage()
. This instructs Mockito to check if there has been a single call to the printTestPage()
method of the Mock Printer.
Note carefully the syntax of the call, the parameter of verify()
is the Mock object, not the method call. If we had put verify(printer.printTestPage())
we would have generated a compile error. Contrast this to the given/when syntax in stubbing which takes the form when(mockObject.someMethod()).thenReturn(...)
.
If we hadn’t called printTestPage()
above this call to verify Mockito would have generated a verification error informing us that there was no invocation of printTestPage()
, which would look like this:
1 2 3 4 | Wanted but not invoked: printer.printTestPage(); -> at com.javacodegeeks.hughwphamill.mockito.stubbing.PrinterTest.simple_interaction_verification(PrinterTest.java:24) Actually, there were zero interactions with this mock. |
Additionally if we had made a second call to printTestPage()
Mockito would have generated a verification error informing us that there were too many invocations of printTestPage()
. This error would look like this:
1 2 3 4 5 6 | org.mockito.exceptions.verification.TooManyActualInvocations: printer.printTestPage(); Wanted 1 time : -> at com.javacodegeeks.hughwphamill.mockito.stubbing.PrinterTest.simple_interaction_verification(PrinterTest.java:25) But was 2 times . Undesired invocation: -> at com.javacodegeeks.hughwphamill.mockito.stubbing.PrinterTest.simple_interaction_verification(PrinterTest.java:22) |
Usefully the error informs us which line of code contained the superfluous invocation – in this case line 22 of PrinterTest.java
.
But what if we want multiple interactions with our Mock? Does Mockito support this? Unsurprisingly the answer is Yes!
The verify()
method takes a second parameter of type org.mockito.verification.VerificationMode
which can be used to provide additional details about the desired interactions with the mock.
2.1. Using the built in Verification Modes
As usual Mockito provides a number of convenient static methods in org.mockito.Mockito for creating VerificationModes, such as:
times(int)
This will verify that the method was called the input number of times.
01 02 03 04 05 06 07 08 09 10 | @Test public void simple_interaction_verification_times_1() { // Given // When printer.printTestPage(); // Then verify(printer, times( 1 )).printTestPage(); } |
Note that verify(mock)
is an alias of verify(mock, times(1))
.
Of course we can verify multiple interactions using times()
01 02 03 04 05 06 07 08 09 10 11 12 | @Test public void simple_interaction_verification_times_3() { // Given // When printer.printTestPage(); printer.printTestPage(); printer.printTestPage(); // Then verify(printer, times( 3 )).printTestPage(); } |
This VerificationMode
will generate useful errors when the actual number of invocations doesn’t match the expected number.
Not enough invocations:
1 2 3 4 5 6 | org.mockito.exceptions.verification.TooLittleActualInvocations: printer.printTestPage(); Wanted 3 times : -> at com.javacodegeeks.hughwphamill.mockito.stubbing.PrinterTest.simple_interaction_verification_times_3(PrinterTest.java:49) But was 2 times : -> at com.javacodegeeks.hughwphamill.mockito.stubbing.PrinterTest.simple_interaction_verification_times_3(PrinterTest.java:45) |
Too many invocations:
1 2 3 4 5 6 | org.mockito.exceptions.verification.TooManyActualInvocations: printer.printTestPage(); Wanted 3 times : -> at com.javacodegeeks.hughwphamill.mockito.stubbing.PrinterTest.simple_interaction_verification_times_3(PrinterTest.java:50) But was 4 times . Undesired invocation: -> at com.javacodegeeks.hughwphamill.mockito.stubbing.PrinterTest.simple_interaction_verification_times_3(PrinterTest.java:47) |
atLeastOnce()
, atLeast(int)
This will verify that the method was called at least the given number of times.
01 02 03 04 05 06 07 08 09 10 11 | @Test public void simple_interaction_verification_atleastonce() { // Given // When printer.printTestPage(); printer.printTestPage(); // Then verify(printer, atLeastOnce()).printTestPage(); } |
01 02 03 04 05 06 07 08 09 10 11 12 | @Test public void simple_interaction_verification_atleast_2() { // Given // When printer.printTestPage(); printer.printTestPage(); printer.printTestPage(); // Then verify(printer, atLeast( 2 )).printTestPage(); } |
As usual we get comprehensive error reporting:
1 2 3 4 5 6 | org.mockito.exceptions.verification.TooLittleActualInvocations: printer.printTestPage(); Wanted *at least* 2 times : -> at com.javacodegeeks.hughwphamill.mockito.stubbing.PrinterTest.simple_interaction_verification_atleast_2(PrinterTest.java:76) But was 1 time : -> at com.javacodegeeks.hughwphamill.mockito.stubbing.PrinterTest.simple_interaction_verification_atleast_2(PrinterTest.java:71) |
atMost(int)
This will verify that the method was called at most the given number of times.
01 02 03 04 05 06 07 08 09 10 11 | @Test public void simple_interaction_verification_atmost_3() { // Given // When printer.printTestPage(); printer.printTestPage(); // Then verify(printer, atMost( 3 )).printTestPage(); } |
And the error condition:
1 2 3 | org.mockito.exceptions.base.MockitoAssertionError: Wanted at most 3 times but was 4 at com.javacodegeeks.hughwphamill.mockito.stubbing.PrinterTest.simple_interaction_verification_atmost_3(PrinterTest.java:91) |
never()
This will verify that the method was not called.
1 2 3 4 5 6 7 8 9 | @Test public void simple_interaction_verification_never() { // Given // When // Then verify(printer, never()).printTestPage(); } |
And the error condition:
1 2 3 4 5 6 | org.mockito.exceptions.verification.NeverWantedButInvoked: printer.printTestPage(); Never wanted here: -> at com.javacodegeeks.hughwphamill.mockito.stubbing.PrinterTest.simple_interaction_verification_never(PrinterTest.java:102) But invoked here: -> at com.javacodegeeks.hughwphamill.mockito.stubbing.PrinterTest.simple_interaction_verification_never(PrinterTest.java:98) |
only()
This will verify that the method being verified was the only method of the mock called.
01 02 03 04 05 06 07 08 09 10 | @Test public void simple_interaction_verification_only() { // Given // When printer.printTestPage(); // Then verify(printer, only()).printTestPage(); } |
We can produce an error by adding the following method to our printer interface:
1 | void turnOff(); |
And calling it in our test
01 02 03 04 05 06 07 08 09 10 11 | @Test public void simple_interaction_verification_only_fails() { // Given // When printer.printTestPage(); printer.turnOff(); // Then verify(printer, only()).printTestPage(); } |
to give the following error:
1 2 3 4 5 6 7 8 9 | org.mockito.exceptions.verification.NoInteractionsWanted: No interactions wanted here: -> at com.javacodegeeks.hughwphamill.mockito.stubbing.PrinterTest.simple_interaction_verification_only_fails(PrinterTest.java:124) But found this interaction: -> at com.javacodegeeks.hughwphamill.mockito.stubbing.PrinterTest.simple_interaction_verification_only_fails(PrinterTest.java:120) *** For your reference, here is the list of all invocations ([?] - means unverified). 1. [?]-> at com.javacodegeeks.hughwphamill.mockito.stubbing.PrinterTest.simple_interaction_verification_only_fails(PrinterTest.java:120) 2. [?]-> at com.javacodegeeks.hughwphamill.mockito.stubbing.PrinterTest.simple_interaction_verification_only_fails(PrinterTest.java:121) |
2.2. Creating a custom Verification Mode
You can create your own custom verification mode by implementing the org.mockito.verification.VerificationMode
interface. Note that this is using some classes that don’t form part of the public API of Mockito. There are plans to promote them to public API as of the time of writing, but this feature should be used with caution in case the implementation changes before that happens.
VerificationMode
exposes a single void verify(VerificationData data)
method which is used to verify that the mock invocations we are interested in happend correctly.
You can use a couple of internal Mockito classes to help you in your VerificationMode
:
InvocationsFinder
will return a list of all invocations with the mock of interest.InvocationMarker
can be used to mark the mock invocation as verified.Reporter
exposes a number of shortcut methods for throwing variousVerificationFailure
errors.InvocationMatcher
is used in conjunction withInvocationsMarker
to find the desired Invocations if they happened.
We are going to create a VerificationMode
called First
which will verify that a given method was the first invocation on the Mock. We will create a class which implements VerificationMode
and in the verify method we will find all matching invocations and verify two things:
1. The invocation we wanted actually happened, if it did not we will use Reporter to throw a “wanted but not invoked” error.
2. The invocation we wanted was the first invocation on the Mock, if it was not we will throw a new exception with an appropriate message detailing the expected invocation and the actual one.
Lastly we will expose the creating of First
through a static factory method to be consistent with the Mockito syntax.
The class First
looks like this:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | package com.javacodegeeks.hughwphamill.mockito.verification; import java.util.Arrays; import java.util.List; import org.mockito.exceptions.Reporter; import org.mockito.exceptions.verification.VerificationInOrderFailure; import org.mockito.internal.debugging.LocationImpl; import org.mockito.internal.invocation.InvocationMarker; import org.mockito.internal.invocation.InvocationMatcher; import org.mockito.internal.invocation.InvocationsFinder; import org.mockito.internal.verification.api.VerificationData; import org.mockito.invocation.Invocation; import org.mockito.verification.VerificationMode; public class First implements VerificationMode { private final InvocationsFinder finder = new InvocationsFinder(); private final InvocationMarker marker = new InvocationMarker(); private final Reporter reporter = new Reporter(); public static VerificationMode first() { return new First(); } @Override public void verify(VerificationData data) { List<Invocation> invocations = data.getAllInvocations(); InvocationMatcher matcher = data.getWanted(); List<Invocation> chunk = finder.findInvocations(invocations, matcher); if (invocations.size() == 0 || chunk.size() == 0 ) { reporter.wantedButNotInvoked(matcher); } else if (!sameInvocation(invocations.get( 0 ), chunk.get( 0 ))) { reportNotFirst(chunk.get( 0 ), invocations.get( 0 )); } marker.markVerified(chunk.get( 0 ), matcher); } private boolean sameInvocation(Invocation left, Invocation right) { if (left == right) { return true ; } return left.getMock().equals(right.getMock()) && left.getMethod().equals(right.getMethod()) && Arrays.equals(left.getArguments(), right.getArguments()); } private void reportNotFirst(Invocation wanted, Invocation unwanted) { StringBuilder message = new StringBuilder(); message.append( "\\nWanted first:\\n" ).append(wanted).append( "\\n" ).append( new LocationImpl()); message.append( "\\nInstead got:\\n" ).append(unwanted).append( "\\n" ).append(unwanted.getLocation()).append( "\\n" ); throw new VerificationInOrderFailure(message.toString()); } } |
We can use it in a test case like this:
01 02 03 04 05 06 07 08 09 10 11 | @Test public void simple_interaction_verification_first() { // Given // When printer.printTestPage(); printer.turnOff(); // Then verify(printer, first()).printTestPage(); } |
Or to catch some unexpected behaviour:
01 02 03 04 05 06 07 08 09 10 11 | @Test public void simple_interaction_verification_first_fails() { // Given // When printer.turnOff(); printer.printTestPage(); // Then verify(printer, first()).printTestPage(); } |
Which generates the following error:
1 2 3 4 5 6 7 | org.mockito.exceptions.verification.VerificationInOrderFailure: Wanted first: printer.printTestPage(); -> at com.javacodegeeks.hughwphamill.mockito.verification.PrinterTest.simple_interaction_verification_first_fails(PrinterTest.java:152) Instead got: printer.turnOff(); -> at com.javacodegeeks.hughwphamill.mockito.verification.PrinterTest.simple_interaction_verification_first_fails(PrinterTest.java:148) |
2.3. Verification with Parameters
We are going to examine verification of methods which take parameters so let’s update our Printer
interface to add a new method. This method will simulate printing a String of text and will contain the following parameters:
- String text – The text to be printed.
- Integer copies – The number of copies to be made.
- Boolean collate – True to collate copies.
1 2 3 4 5 6 7 8 9 | public interface Printer { void printTestPage(); void turnOff(); void print(String text, Integer copies, Boolean collate); } |
Verification with Parameters lets us verify that not only was there an interaction with a Mock
, but what parameters were passed to the Mock. To perform verification with parameters you simply pass the parameters of interest into the Mocked method on the verify call on the Mock.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 | @Test public void verificatin_with_actual_parameters() { // Given String text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." ; Integer copies = 3 ; Boolean collate = true ; // When printer.print(text, copies, collate); // Then verify(printer).print(text, copies, collate); } |
Note carefully again the syntax of verify()
we are calling print()
on the object returned from the verify method, not directly on the Mock. You can see that simply passing in the values to print()
is enough to perform verification using parameters.
The following test will fail:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 | @Test public void verificatin_with_actual_parameters_fails() { // Given String text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." ; String text2 = "Ut enim ad minim veniam, quis nostrud exercitation ullamco " + "laboris nisi ut aliquip ex ea commodo consequat." ; Integer copies = 3 ; Boolean collate = true ; // When printer.print(text2, copies, collate); // Then verify(printer).print(text, copies, collate); } |
with the following output:
01 02 03 04 05 06 07 08 09 10 11 12 13 | Argument(s) are different! Wanted: printer.print( "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." , 3, true ); -> at com.javacodegeeks.hughwphamill.mockito.verification.PrinterTest.verificatin_with_actual_parameters_fails(PrinterTest.java:185) Actual invocation has different arguments: printer.print( "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat." , 3, true ); |
You can see that Mockito usefully gives you the expected arguments and the actual arguments in the error trace, making it very easy to debug your failing test.
As with simple verification we can use a VerificationMode to do more specific verification when using Parameters. The crucial difference is that the VerificationMode we specify applies only to invocations with the stated parameters. So if we use a verification mode of never()
, for instance, we are stating that the method is never called with the stated parameters, not that it is never called at all.
The following test passes because even though the print()
method is invoked, it is never invoked with the specified parameters.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 | @Test public void verification_with_actual_parameters_and_verification_mode() { // Given String text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." ; String text2 = "Ut enim ad minim veniam, quis nostrud exercitation ullamco " + "laboris nisi ut aliquip ex ea commodo consequat." ; Integer copies = 3 ; Boolean collate = true ; // When printer.print(text, copies, collate); // Then verify(printer, never()).print(text2, copies, collate); } |
When we have multiple calls to our Mock
we can verify each one individually using multiple calls to verify
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 | @Test public void multiple_verification_with_actual_parameters() { // Given String text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." ; String text2 = "Ut enim ad minim veniam, quis nostrud exercitation ullamco " + "laboris nisi ut aliquip ex ea commodo consequat." ; Integer copies = 3 ; Boolean collate = true ; // When printer.print(text, copies, collate); printer.print(text2, copies, collate); // Then verify(printer).print(text, copies, collate); verify(printer).print(text2, copies, collate); } |
A lot of the time we aren’t interested or don’t know what the actual parameters of the interaction will be, in these instances, just as in the Stubbing phase we can use Argument Matchers to verify interactions.
Look at the following test
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 | @Test public void verification_with_matchers() { // Given String text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." ; String text2 = "Ut enim ad minim veniam, quis nostrud exercitation ullamco " + "laboris nisi ut aliquip ex ea commodo consequat." ; Integer copies3 = 3 ; Integer copies4 = 4 ; Boolean doCollate = true ; Boolean doNotCollate = false ; // When printer.print(text, copies3, doCollate); printer.print(text2, copies4, doNotCollate); // Then verify(printer, times( 2 )).print(anyString(), anyInt(), anyBoolean()); } |
Note that we call printer.print()
twice, with completely different parameters each time. We verify both interactions with the Mock on the last line using Argument Matchers. Remember that verify(printer).print()
implicitly means we want to verify one and only one interaction with the print()
method on the Mock, so we must include the times(2)
VerificationMode to ensure we are verifying both interactions with the Mock.
The Argument Matchers used with Verification are the same Argument Matchers used during the Stubbing phase. Please revisit the Stubbing tutorial for a longer list of available Matchers.
As with the Stubbing phase we cannot mix and match Argument Matchers with real values, but what if we didn’t care about the text that was passed into the Printer for printing, we were only interested in verifying that there should be 5 collated copies?
In this case, as with Stubbing, we can use the eq()
Matcher to verify the real values we are interested, while using anyString()
for the text.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 | @Test public void verification_with_mixed_matchers() { // Given String text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." ; String text2 = "Ut enim ad minim veniam, quis nostrud exercitation ullamco " + "laboris nisi ut aliquip ex ea commodo consequat." ; Integer copies = 5 ; Boolean collate = true ; // When printer.print(text, copies, collate); printer.print(text2, copies, collate); // Then verify(printer, times( 2 )).print(anyString(), eq(copies), eq(collate)); } |
This passes, while the following test will fail
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 | @Test public void verification_with_mixed_matchers_fails() { // Given String text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." ; Integer copies5 = 5 ; Integer copies10 = 10 ; Boolean collate = true ; // When printer.print(text, copies10, collate); // Then verify(printer).print(anyString(), eq(copies5), eq(collate)); } |
2.4. Verification with Timeout
Sometimes, when testing multithreaded applications, we want to ensure that certain mock interactions happen within a given timeout period. Mockito provides a timeout()
method to help us achieve this.
Please note that while this feature is available, the Mockito documentation cautions against using it:
“It feels this feature should be used rarely – figure out a better way of testing your multi-threaded system.”
So with the health warning out of the way let’s look at a couple of examples.
Let’s say we have some thread that’s going to execute a printTestPage()
and we want to verify that this happens within 100 milliseconds. We can use timeout(100)
to achieve this. It can be passed as the second parameter to verify()
and it returns a VerificationWithTimout which is an extension of VerificationMode.
The following test demonstrates it’s usage:
01 02 03 04 05 06 07 08 09 10 | @Test public void verification_with_timeout() { // Given // When Executors.newFixedThreadPool( 1 ).execute(() -> printer.printTestPage()); // Then verify(printer, timeout( 100 )).printTestPage(); } |
Here we create a new ExecutorService
using Executor
s which can execute Runnables. We take advantage of Java 8 Lambda expressions to build a new Runnable
on the fly which will execute a call to printTestPage()
. We then call verify()
passing in a timeout of 100ms.
We can look at a failing test now. This time we will use a method reference to generate the Runnable, this is because the body of our Runnable is a bit more complex – it introduces a sleep for 200ms.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 | @Test public void verification_with_timeout_fails() throws InterruptedException { // Given // When Executors.newFixedThreadPool( 1 ).execute( this ::printTestWithSleep); // Then verify(printer, timeout( 100 )).printTestPage(); } private void printTestWithSleep() { try { Thread.sleep(200L); printer.printTestPage(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } |
The test fails with a simple ‘wanted but not invoked’ message.
It is also possible to add VerificationModes to timeout()
using methods exposed by the returned VerificationWithTimeout
.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 | @Test public void verification_with_timeout_with_verification_mode() { // Given int poolsize = 5 ; // When ExecutorService service = Executors.newFixedThreadPool(poolsize); service.execute( this ::printTestWithSleep); service.execute( this ::printTestWithSleep); service.execute( this ::printTestWithSleep); // Then verify(printer, timeout( 500 ).times( 3 )).printTestPage(); } |
Here we use the test with sleep to execute printTestPage()
3 times, we use an ExecutorService
that can run 5 parallel threads so the sleeps happen at the same time, allowing all 3 invocations to occur within the 500ms limit.
We can make the test fail by reducing the number of available threads to 1, forcing the printTestWithSleep calls to execute sequentially and going over the 500ms timeout.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 | @Test public void verification_with_timeout_with_verification_mode_fails() { // Given int poolsize = 1 ; // When ExecutorService service = Executors.newFixedThreadPool(poolsize); service.execute( this ::printTestWithSleep); service.execute( this ::printTestWithSleep); service.execute( this ::printTestWithSleep); // Then verify(printer, timeout( 500 ).times( 3 )).printTestPage(); } |
The first 2 calls happen within 400ms while the last one will happen after 600ms, causing the timeout of 500ms to fail with the following output:
1 2 3 4 5 6 | org.mockito.exceptions.verification.TooLittleActualInvocations: printer.printTestPage(); Wanted 3 times : -> at com.javacodegeeks.hughwphamill.mockito.verification.PrinterTest.verification_with_timeout_with_verification_mode_fails(PrinterTest.java:410) But was 2 times : -> at com.javacodegeeks.hughwphamill.mockito.verification.PrinterTest.printTestWithSleep(PrinterTest.java:376) |
3. Verifying No Interactions and No More Interactions
We saw already that we can use the never()
VerificationMode to ensure that a particular method of a Mock is not invoked, but what about verifying that there are no interactions on a Mock at all?
Mockito provides us with the verifyZeroInteractions()
method to do just that. This method uses varargs to allow us to verify no interactions with several mocks in one line of code.
Let’s add some other Mock to our test class:
1 2 | @Mock private List<String> list; |
Now we can write the following simplistic test to verify no interactions with the Printer or the List
1 2 3 4 5 6 7 8 9 | @Test public void verify_zero_interactions() { // Given // When // Then verifyZeroInteractions(printer, list); } |
As usual, the following test will fail
01 02 03 04 05 06 07 08 09 10 | @Test public void verify_zero_interactions_fails() { // Given // When printer.printTestPage(); // Then verifyZeroInteractions(printer, list); } |
With the following output
1 2 3 4 5 6 7 | org.mockito.exceptions.verification.NoInteractionsWanted: No interactions wanted here: -> at com.javacodegeeks.hughwphamill.mockito.verification.PrinterTest.verify_zero_interactions_fails(PrinterTest.java:288) But found this interaction: -> at com.javacodegeeks.hughwphamill.mockito.verification.PrinterTest.verify_zero_interactions_fails(PrinterTest.java:285) Actually, above is the only interaction with this mock. at com.javacodegeeks.hughwphamill.mockito.verification.PrinterTest.verify_zero_interactions_fails(PrinterTest.java:288) |
We can also verify that once a certain number of invocations have been verified there are no more interactions with the Mock, using the verifyNoMoreInteractions()
method.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 | @Test public void verify_no_more_interactions() { // Given String text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." ; Integer copies = 3 ; Boolean collate = true ; // When printer.print(text, copies, collate); // Then verify(printer).print(text, copies, collate); verifyNoMoreInteractions(printer); } |
You can see above that we verify the call to print()
and then verify that there are no more interactions with the Mock.
The following test will fail because there was an additional interaction with the mock after the verified call to print()
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 | @Test public void verify_no_more_interactions_fails() { // Given String text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." ; Integer copies = 3 ; Boolean collate = true ; // When printer.print(text, copies, collate); printer.turnOff(); // Then verify(printer).print(text, copies, collate); verifyNoMoreInteractions(printer); } |
The failing test generates the following message:
1 2 3 4 5 6 7 8 9 | org.mockito.exceptions.verification.NoInteractionsWanted: No interactions wanted here: -> at com.javacodegeeks.hughwphamill.mockito.verification.PrinterTest.verify_no_more_interactions_fails(PrinterTest.java:342) But found this interaction: -> at com.javacodegeeks.hughwphamill.mockito.verification.PrinterTest.verify_no_more_interactions_fails(PrinterTest.java:338) *** For your reference, here is the list of all invocations ([?] - means unverified). 1. -> at com.javacodegeeks.hughwphamill.mockito.verification.PrinterTest.verify_no_more_interactions_fails(PrinterTest.java:337) 2. [?]-> at com.javacodegeeks.hughwphamill.mockito.verification.PrinterTest.verify_no_more_interactions_fails(PrinterTest.java:338) |
4. Verification in Order
Sometimes we want to verify that interactions with our Mocks happened in a particular order. Mockito provides a class called InOrder
to help us achieve this.
The first thing we need to do is register the mocks that we want to confirm the invocation order on with the InOrder object. We then execute methods on the Mock object, and then call the verify()
method of the InOrder
object for each mock method for which we want to confirm the ordered executions, in the order in which we want to verify they happened.
The InOrder.verify()
method behaves almost like the standard verify()
method, allowing you to pass in VerificationModes, however you can’t do Verification With Timeout with InOrder.
Here is an example of verification in order in action:
01 02 03 04 05 06 07 08 09 10 11 12 13 | @Test public void verify_in_order() { // Given InOrder inOrder = Mockito.inOrder(printer); // When printer.printTestPage(); printer.turnOff(); // Then inOrder.verify(printer).printTestPage(); inOrder.verify(printer).turnOff(); } |
And the converse failing test:
01 02 03 04 05 06 07 08 09 10 11 12 13 | @Test public void verify_in_order_fails() { // Given InOrder inOrder = Mockito.inOrder(printer); // When printer.turnOff(); printer.printTestPage(); // Then inOrder.verify(printer).printTestPage(); inOrder.verify(printer).turnOff(); } |
Which fails with the following error message:
1 2 3 4 5 6 7 8 | org.mockito.exceptions.verification.VerificationInOrderFailure: Verification in order failure Wanted but not invoked: printer.turnOff(); -> at com.javacodegeeks.hughwphamill.mockito.verification.PrinterTest.verify_in_order_fails(PrinterTest.java:440) Wanted anywhere AFTER following interaction: printer.printTestPage(); -> at com.javacodegeeks.hughwphamill.mockito.verification.PrinterTest.verify_in_order_fails(PrinterTest.java:436) |
You can also Verify In Order across multiple Mocks:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 | @Test public void verify_in_order_multiple() { // Given InOrder inOrder = Mockito.inOrder(printer, list); // When printer.printTestPage(); list.clear(); printer.turnOff(); // Then inOrder.verify(printer).printTestPage(); inOrder.verify(list).clear(); inOrder.verify(printer).turnOff(); } |
5. Argument Captors
We have looked at using Argument Matchers for verifying invocations with particular parameters but Mockito lets us go further than this, capturing the parameters which were passed into the invocation and performing asserts directly on them. This is very useful for verifying log in your class which is performed on objects which will be passed to collaborators. The facility for doing this is a class called ArgumentCaptor
and an annotation called @Captor
.
Let’s make a new class in our model called PrinterDiagnostics
. It will contain a Printer and expose a method called diagnosticPrint
, which will have the same parameters as Printer.print()
and add some diagnostic information to the text being printed.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 | package com.javacodegeeks.hughwphamill.mockito.verification; public class PrinterDiagnostics { private Printer printer; public PrinterDiagnostics(Printer printer) { this .printer = printer; } public void diagnosticPrint(String text, Integer copies, Boolean collate) { StringBuilder diagnostic = new StringBuilder(); diagnostic.append( "** Diagnostic Print **\\n" ); diagnostic.append( "*** Copies: " ).append(copies).append( " ***\\n" ); diagnostic.append( "*** Collate: " ).append(collate).append( " ***\\n" ); diagnostic.append( "********************\\n\\n" ); printer.print( new StringBuilder().append(diagnostic).append(text).toString(), copies, collate); } } |
We’ll create a new JUnit test to test this class, using a Mock Printer
and an ArgumentCaptor
which we’ll use to verify the input to the Printer.
Here’s the skeleton of the JUnit test:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | package com.javacodegeeks.hughwphamill.mockito.verification; import org.junit.Before; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; @RunWith (MockitoJUnitRunner. class ) public class PrinterDiagnosticsTest { private PrinterDiagnostics diagnostics; @Mock private Printer printer; @Captor private ArgumentCaptor<String> textCaptor; @Before public void setUp() throws Exception { diagnostics = new PrinterDiagnostics(printer); } } |
Here we see that we create an instance of the class under test, diagnostics, a Mock to represent the printer, printer, and an ArgumentCaptor for String arguments to capture the text input to the printer called textCaptor. You can see that we annotated the ArgumentCaptor with the @Captor
annotation; Mockito will automatically instantiate the ArgumentCaptor for us because we used the annotation.
You can also see that ArgumentCaptor is a Generic type, we create an ArgumentCaptor with Type Argument String in this case because we are going to be capturing the text argument, which is a String. If we were capturing the collate parameter we might have created ArgumentCaptor
.
In our @Before
method we simply create a new PrinterDiagnostics
., injecting our mock Printer through its constructor.
Now let’s create our test. We want to ensure two things:
1. The number of copies is added to the input text.
2. The state of the collate parameter is added to the input text.
3. The original text is maintained.
We could also want to verify the formatting and the asterisks in the real world, but for now let’s content ourselves with verifying the two criteria above.
In the test we will initialize the test data, execute the call to diagnosticPrint()
and then use verify()
in conjunction with the capture()
method of ArgumentCaptor to capture the text argument. We will then do necessary asserts on the captured String to verify the behaviour we expect by using the getValue()
method to retrieve the captured text.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 | @Test public void verify_diagnostic_information_added_to_text() { // Given String text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." ; Integer copies = 3 ; Boolean collate = true ; String expectedCopies = "Copies: " + copies; String expectedCollate = "Collate: " + collate; // When diagnostics.diagnosticPrint(text, copies, collate); // Then verify(printer).print(textCaptor.capture(), eq(copies), eq(collate)); assertTrue(textCaptor.getValue().contains(expectedCopies)); assertTrue(textCaptor.getValue().contains(expectedCollate)); assertTrue(textCaptor.getValue().contains(text)); } |
Note that capture()
acts a bit like a Matcher in that you have to use Matchers for the other parameters. We use the eq()
matcher to ensure we pass through the expected copies and collate parameters.
If there are multiple invocations on the mocked method we can use the getValues()
method of ArgumentCaptor
to get a List of all the Strings which were passed through as the text parameter in each call.
Let’s create a new method in PrinterDiagnostics which will perform a diagnostic print of a single collated copy as well as the original print:
1 2 3 4 | public void diagnosticAndOriginalPrint(String text, Integer copies, Boolean collate) { diagnosticPrint(text, copies, collate); printer.print(text, copies, collate); } |
We can now test this with the following test method:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | @Test public void verify_diagnostic_information_added_to_text_and_original_print() { // Given String text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, " + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." ; Integer copies = 3 ; Boolean collate = true ; String expectedCopies = "Copies: " + copies; String expectedCollate = "Collate: " + collate; // When diagnostics.diagnosticAndOriginalPrint(text, copies, collate); // Then verify(printer, times( 2 )).print(textCaptor.capture(), eq(copies), eq(collate)); List<String> texts = textCaptor.getAllValues(); assertEquals( 2 , texts.size()); // First captured text is Diagnostic Print assertTrue(texts.get( 0 ).contains(expectedCopies)); assertTrue(texts.get( 0 ).contains(expectedCollate)); assertTrue(texts.get( 0 ).contains(text)); // Second captured text is normal Print assertFalse(texts.get( 1 ).contains(expectedCopies)); assertFalse(texts.get( 1 ).contains(expectedCollate)); assertEquals(text, texts.get( 1 )); } |
Note that we have to use times(2)
in our verification because we are expecting to invoke the print()
method twice.
ArgumentCaptors are particularly useful when our parameters are complex objects or are created by the code under test. You can easily capture the argument and do any type of verification and validation you need on it.
6. Conclusion
We have looked in detail at the verification phase of Mockito. We have examined the ways which we can verify behaviour out of the box, create our own Verification Modes and use Argument Captors for doing further more complex assertions on our Data.
In the next tutorial we will examine how the Hamcrest Matcher library lets us take our test verification even further, allowing us to do very fine grained behavioural validation.
7. Download the Source Code
This was a lesson on Mockito Verification. You may download the source code here: mockito3-verification