Mockito List Matcher Example
In the Mockito Tutorial for Beginners, we saw a general overview of the use of Mockito framework for Java unit tests. In this example,we will see how are and how to use the Mockito Matchers for List
elements.
For this example, we will use:
- Java 1.7.0
- Eclipse Mars 2, release 4.5.2.
- JUnit 4.
- Mockito 1.10.19.
You may skip project creation and jump directly to the beginning of the example below.
1. Project creation
Go to “File/New/Java Project”. You will be asked to enter a name for the project. Then, press “Next”, not “Finish”.
In the new window that has appeared, go to “Libraries” tab, select “Add library” button, and then select “JUnit”, as shown in the following images below:
You can now finish the project creation.
Now, right click the folder icon in the Package Explorer, and select “New/Source Folder”, and enter the name you want to give to the test folder.
1.1. Mockito installation
The easiest way to install Mockito is:
- Download it directly from Maven Repository.
- Place it inside your working directory, for example, in a lib directory in the directory root.
- Refresh the Package Explorer in Eclipse (F5).
- Now, a new lib directory should be displayed, with the Mockito JAR file inside it. Right click on it an select “Build Path/Add to Build Path” (shown in image below).
2. Base code
Let’s create a very simple project. We will suppose that we need to deal with a List
, without specifying the implementation, where elements will be added and removed. We could create an interface like the following:
ListHandler.java
package com.javacodegeeks.listmatcher.handler; import java.util.List; public interface ListHandler { /** * Adds an element to the specified list implementation. * * @param list An implementation of List. * @param element The element to add. * @return The returned value by list. */ public boolean add(List<?> list, Object element); /** * Removes the element at the specified position from the list implementation. * * @param list An implementation of List. * @param index The index to be removed. * @return The element previously at the specified position. */ public Object remove(List<?> list, int index); }
As you can see, we don’t know neither the List
implementation (which could be an ArrayList
, LinkedList
, and any other implementation of the Java API; or even our own list), nor the list type.
Let’s see how we can easily mock this interface with Mockito, even if we don’t know what parameters provide to it.
3. Mocking the interface
We want to mock the previously defined interface. In this case, the creation of the mock is exactly the same as in other scenarios:
ListHandlerTest.java
package com.javacodegeeks.listmatcher.handler; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.junit.Before; import org.junit.Test; import org.mockito.Matchers; import org.mockito.Mockito; public class ListHandlerTest { private ListHandler listHandlerMock; @Before public void setUp() { listHandlerMock = Mockito.mock(ListHandler.class); } }
Just as with any other mock.
Now, is time to mock its methods, e.g., add()
method. The first thing one can think is to do something like the following:
// ... when(this.listHandlerMock.add(new ArrayList<String>(), // etc. // ...
Which is actually not bad. But Mockito offers a much more elegant solution. This is achieved using the Mockito Matchers
, for lists, in this case. This is how they are used:
ListHandlerTest.java
// ... @Test public void testAdd() { boolean actual = true; when(this.listHandlerMock.add( Matchers.anyList(), Matchers.any() )).thenReturn(true); actual = this.listHandlerMock.add(Matchers.anyList(), Matchers.any()); assertTrue(actual); verify(this.listHandlerMock).add( Matchers.anyList(), Matchers.any() ); }
Note that elements used in lines 8, 9, 12, 16, 17. These are the Mockito matchers.
Their use would be like saying “we want to mock some implementation of a List with some parameter, and as we don’t mind which use, we tell the compiler that anyone is okay“.
3.1. Things to take into account
There are a couple of things that we have to know:
- If we are using a matcher when stubbing a method, every parameter has to be expressed with a matcher. That is, something like the following would throw an exception in runtime:
// ... when(this.listHandlerMock.add( Matchers.anyList(), "A value" // Illegal; a Matcher has to be used. )).thenReturn(true); // ...
- Deducible from the previous one, using Matchers, we cannot restrict the parameter to a concrete type. We have to assume that the parameter can be of any type. That is, the following test:
// ... @Test public void testAdd() { boolean actual = true; when(this.listHandlerMock.add( Matchers.anyList(), Matchers.anyString() )).thenReturn(true); actual = this.listHandlerMock.add(Matchers.anyList(), Matchers.anyString()); assertTrue(actual); verify(this.listHandlerMock).add( Matchers.anyList(), Matchers.anyInt() ); } // ...
Would pass as valid, even if we have stubbed and invoked the method with anyString()
(lines 9 and 12, respectively), and then verified the behavior with anyInt()
.
4. Matchers for other elements
Apart from lists, Mockito offers matchers for other classes (apart from native types). You can see them in the Mockito matchers documentation for 1.10.19 version, but here’s a list with the matchers for parameterizable classes:
- Maps.
- Collections.
- Sets.
Their use is the same as for the lists, Matchers.anyMap()
, etc.
4.1. Don’t use “any’Interface’Of” matcher
If you check the documentation mentioned above, you may see that there are available matchers for lists, maps, etc. with the “-Of” suffix. Even if it could seem that are thought for restricting the interface implementation, they actually do nothing. Moreover, all of them are marked as deprecated in Mockito 2.0.96 beta documentation, mentioning that they will be removed with next major version.
5. Summary
This example has shown how to use Mockito matchers for lists, used when mocking methods that receive objects of classes allowing wildcards (among others). Apart from that, we have also seen what Mockito matchers don’t do or what are not thought for, since their use can lead to confusion.
6. Download the Eclipse Project
This was an example of Mockito list matchers.
You can download the full source code of this example here: MockitoListMatchersExample