Core Java

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!

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.

public interface Printer {
	
	void printTestPage();

}

We can create a simple unit test to demonstrate verify using a Mock Printer

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:

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:

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.

@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()

@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:

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:

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.

@Test
public void simple_interaction_verification_atleastonce() {
	// Given
		
	// When
	printer.printTestPage();
	printer.printTestPage();
		
	// Then
	verify(printer, atLeastOnce()).printTestPage();		
}
@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:

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.

@Test
public void simple_interaction_verification_atmost_3() {
	// Given
		
	// When
	printer.printTestPage();
	printer.printTestPage();
		
	// Then
	verify(printer, atMost(3)).printTestPage();		
}

And the error condition:

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.

@Test
public void simple_interaction_verification_never() {
	// Given
		
	// When
		
	// Then
	verify(printer, never()).printTestPage();		
}

And the error condition:

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.

@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:

void turnOff();

And calling it in our test

@Test
public void simple_interaction_verification_only_fails() {
	// Given
		
	// When
	printer.printTestPage();
	printer.turnOff();
		
	// Then
	verify(printer, only()).printTestPage();		
}

to give the following error:

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 various VerificationFailure errors.
  • InvocationMatcher is used in conjunction with InvocationsMarker 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:

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:

@Test
public void simple_interaction_verification_first() {
	// Given
		
	// When
	printer.printTestPage();
	printer.turnOff();		
				
	// Then
	verify(printer, first()).printTestPage();		
}

Or to catch some unexpected behaviour:

@Test
public void simple_interaction_verification_first_fails() {
	// Given
		
	// When
	printer.turnOff();
	printer.printTestPage();				
				
	// Then
	verify(printer, first()).printTestPage();		
}

Which generates the following error:

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.
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.

@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:

@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:

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.

@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

@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

@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.

@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

@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:

@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 Executors 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.

@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.

@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.

@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:

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:

@Mock
private List<String> list;

Now we can write the following simplistic test to verify no interactions with the Printer or the List

@Test
public void verify_zero_interactions() {
	// Given
		
	// When
				
	// Then
	verifyZeroInteractions(printer, list);		
}

As usual, the following test will fail

@Test
public void verify_zero_interactions_fails() {
	// Given
		
	// When
	printer.printTestPage();
				
	// Then
	verifyZeroInteractions(printer, list);		
}

With the following output

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.

@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()

@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:

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:

@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:

@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:

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:

@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.

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:

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 collateCaptor.

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.

@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:

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:

@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

Hugh Hamill

Hugh is a Senior Software Engineer and Certified Scrum Master based in Galway, Ireland. He achieved his B.Sc. in Applied Computing from Waterford Institute of Technology in 2002 and has been working in industry since then. He has worked for a several large blue chip software companies listed on both the NASDAQ and NYSE.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button