Mockito

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

1. Adding libraries to the project.

2. Adding JUnit as library.

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.

3. Creating folder for tests.

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

4. Adding Mockito to build path.

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.

Download
You can download the full source code of this example here: MockitoListMatchersExample

Julen Pardo

Julen holds his Bachelor's Degree in Computer Engineering from Mondragon Unibertsitatea, in Spain. Currently he is working in Munich, Germany, as Software Engineer. He contributes to open source projects with plugins, and he also develops his own, open-source projects. Julen is continuously trying to learn and adopt Software Engineering principles and practices to build better, more secure, readable and maintainable software.
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