

Today we’re going to take a look at the Mockito framework that not only does sound like my favourite summer cocktail but also offers nice testing, mocking/stubbing, test-spying features and mock injections.

After that we’re going to take a look on how to mock static or final classes by extending Mockito’s capabilities with PowerMock.





Prerequisites

We don’t need much for the following samples .. Java of course, Maven dependency management and that’s all ..

Setup Project

We don’t have much to do here .. we need a mavenized project and one dependency ..

We’re creating a new Maven project using the favourite IDE with Maven support or via command line using mvn archetype:generate

In the next step, we’re adding the dependency for mockito-core to our pom.xml that finally looks like this <?xml version = "1.0" encoding = "utf-16" ?> <project xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" > <modelVersion > 4.0.0 </modelVersion > <groupId > com.hascode.tutorial </groupId > <artifactId > mockito-tutorial </artifactId > <version > 0.0.1 </version > <dependencies > <dependency > <groupId > org.mockito </groupId > <artifactId > mockito-core </artifactId > <version > 1.8.5 </version > <scope > test </scope > </dependency > <dependency > <groupId > junit </groupId > <artifactId > junit </artifactId > <version > 4.8.2 </version > <scope > test </scope > </dependency > </dependencies > </project >

Classes under Test

Before we’re starting to write our tests we need some classes to be tested and mocked.. they’re all created in src/main/java in the package com.hascode.tutorial.





UserBean

package com.hascode.tutorial ; import java.util.Calendar ; public interface UserBean { String getName ( ) ; String setName ( ) ; Calendar getLastLogin ( ) ; void setLastLogin ( Calendar lastLogin ) ; boolean isActive ( ) ; void setActive ( boolean active ) ; }

UserRepository

package com.hascode.tutorial ; import java.util.List ; public interface UserRepository { List < UserBean > findAll ( ) ; void save ( final UserBean user ) ; void remove ( final UserBean user ) ; }

NotificationService

package com.hascode.tutorial ; public interface NotificationService { void notifyUser ( final UserBean user, final String message ) ; }

AccountService

package com.hascode.tutorial ; public class AccountService { private final UserRepository userRepository ; private final NotificationService notificationService ; public AccountService ( final UserRepository userRepository, final NotificationService notificationService ) { this . userRepository = userRepository ; this . notificationService = notificationService ; } public void removeUser ( final UserBean user ) { notificationService. notifyUser ( user, getUserDeletionMessage ( user ) ) ; userRepository. remove ( user ) ; } private String getUserDeletionMessage ( final UserBean user ) { return String . format ( "Dear administrator,

the following user account has been deleted: %s" , user. getName ( ) ) ; } }

Mocking

Mockito is not able to mock static or final classes – I’ll show you how to do this by combining Mockito and PowerMock in the last chapter. For all other stuff we’re able to create mocks using Mockito.mock or – my favourite – annotations and mock injection.

Using static imports might improve the readability of your tests but some programmers dont’t like them .. so it’s your choice .. I only like them in my tests ;)

First a simple mock example mocking the UserRepository package com.hascode.tutorial ; import static org. mockito . Mockito . mock ; import org.junit.Test ; public class SimpleMockExample { @Test public void testSomething ( ) { UserRepository userRepository = mock ( UserRepository. class ) ; } }

Now using mock injection and annotations – the more mocks are used in a test the more you’re going to like this version package com.hascode.tutorial ; import org.junit.Before ; import org.junit.Test ; import org.mockito.Mock ; import org.mockito.MockitoAnnotations ; public class SimpleMockExampleWithAnnotations { @Mock private UserRepository userRepository ; @Before public void setUp ( ) { MockitoAnnotations. initMocks ( this ) ; } @Test public void testSomething ( ) { // ... } }

Since version 1.8 a mock can be resetted using reset(mock) – or in our example reset(userRepository);. More details on this in the section about verification..

Another nice feature (since 1.8) is the @InjectMocks annotation that allows setter injection for mocked dependencies but be aware you need to call MockitoAnnotations.initMocks() to make it work.

Stubbing

Now that we’re able to create mocks the next step is to stub some method calls ..

Stubbing is really easy .. using the following syntax when(mock.method()).thenReturn(..)

In addition it is possible to stub void methods to throw an exception using doThrow(new Exception()).when(mock).method(); The following example mocks the findAll method and returns null and forces the save method to throw a RuntimeException package com.hascode.tutorial ; import static org. mockito . Matchers . any ; import static org. mockito . Mockito . doThrow ; import static org. mockito . Mockito . mock ; import static org. mockito . Mockito . when ; import junit.framework.Assert ; import org.junit.Test ; public class SimpleStubExample { @Test ( expected = RuntimeException . class ) public void testSomething ( ) { UserRepository userRepository = mock ( UserRepository. class ) ; when ( userRepository. findAll ( ) ) . thenReturn ( null ) ; doThrow ( new RuntimeException ( ) ) . when ( userRepository ) . save ( any ( UserBean. class ) ) ; Assert . assertNull ( userRepository. findAll ( ) ) ; userRepository. save ( null ) ; } }

Please note that I have used Mockito’s argument matcher API here and that leads to the following chapter – Argument Matchers :)

Argument Matchers

Mockito offers a variety of argument matchers for flexible verification or stubbing – often used matchers are these:

any() / any(Class<T> clazz): matches any object - the class argument is provided only to avoid casting

matches any object - the class argument is provided only to avoid casting anyBoolean () : matches any boolean value or null

matches any boolean value or null anyByte () : matches any byte or null

matches any byte or null anyChar () : matches any char or null

matches any char or null anyCollection () / anyCollectionOf (Class<T> clazz) : matches any collection (or generic collection) or null

matches any collection (or generic collection) or null anyDouble (): matches any double or null

matches any double or null anyFloat (): matches any float or null

matches any float or null anyInt (): matches any integer or null

matches any integer or null anyList() / anyListOf(Class<T> clazz): matches any list (or generic list) or null

matches any list (or generic list) or null anyMap(): matches any map or null

matches any map or null anySet / anySetOf(Class<T> clazz): matches any set (or generic set) or null

matches any set (or generic set) or null anyString: matches any string or null

matches any string or null and many others .. for a complete list of available matchers and providing custom extensions to the matcher API take a look at the Matcher javadocs.

Please be aware that if you’re using argument matchers, all arguments in verify or stub must be provided by matchers.

Test Spying / Verification

Mockito’s test spy features allow the developer to take a look behind the curtain and verify how often, in which order and how long invocations on a mock object’s method have been triggered.

Verification enables you to test the behaviour of methods with void return but you shouldn’t overuse this feature .. use JUnit’s Assert methods when possible, verify when needed.. more about this topic from the creator of Mockito: Szepan Faber: Is there a difference between asking and telling?

These are our verification methods:

Verify that a method has been called at least once: verify(mock).method() or verify(mock, times(1)).method()

Verify an exact number of incovations: verify(mock, times(number)).method()

Verify that a method has never been called: verify(mock, never()).method() or verify(mock, times(0)).method()

Verify that a method has been called at least n times: verify(mock, atLeast(n)).method()

Verify that a method has been called at most n times: verify(mock, atMost(n)).method()

Take a look at the following example package com.hascode.tutorial ; import static org. mockito . Matchers . any ; import static org. mockito . Matchers . anyString ; import static org. mockito . Mockito . atLeast ; import static org. mockito . Mockito . mock ; import static org. mockito . Mockito . never ; import static org. mockito . Mockito . reset ; import static org. mockito . Mockito . times ; import static org. mockito . Mockito . verify ; import org.junit.Test ; public class VerificationExample { @Test public void testExample ( ) { // mock NotificationService notificationService = mock ( NotificationService. class ) ; UserRepository userRepository = mock ( UserRepository. class ) ; UserBean user = mock ( UserBean. class ) ; // init AccountService service = new AccountService ( userRepository, notificationService ) ; // run service. removeUser ( user ) ; // verify verify ( notificationService, times ( 1 ) ) . notifyUser ( any ( UserBean. class ) , anyString ( ) ) ; // verify // 1 // invocation verify ( userRepository ) . remove ( any ( UserBean. class ) ) ; // verify 1 // invocation, short // syntax reset ( notificationService ) ; // reset the mocks reset ( userRepository ) ; verify ( notificationService, never ( ) ) . notifyUser ( any ( UserBean. class ) , anyString ( ) ) ; service. removeUser ( user ) ; service. removeUser ( user ) ; verify ( notificationService, times ( 2 ) ) . notifyUser ( any ( UserBean. class ) , anyString ( ) ) ; verify ( userRepository, atLeast ( 2 ) ) . remove ( any ( UserBean. class ) ) ; } }

Behaviour Driven Development / BDD Aliases

Since version 1.8.0 Mockito supports aliases for the friends of Behaviour Driven Development – those are only aliases and do not mean that your tests fulfil the BDD paradigm just because there’s a given-when-then syntax :)

The alias for the stub method is given – a full overview of the aliases can be found in the the javadocs for BDDMockito

If you’re going to take a deeper look into BDD please take a look at the following article of mine about BDD and the JBehave framework.

Mocking static or final classes .. PowerMock to the rescue

Often a developer gets into the situation to mock final or static classes from third-party libraries or legacy code. Mockito alone is not able to mock static or final classes .. we could – of course write utility classes using the reflection API or – just take a look at the PowerMock framework.

Mocking static classes/methods is really easy and is achieved passing the following steps:

Add the dependency for the PowerMock Mockito integration to your pom.xml <dependency > <groupId > org.powermock </groupId > <artifactId > powermock-mockito-release-full </artifactId > <version > 1.4.8 </version > <type > pom </type > <scope > test </scope > </dependency >

Run your unit test with @RunWith(PowerMockRunner.class)

Prepare the static class to be mocked using @PrepareForTest(Static.class) at class level

Call PowerMockito.mockStatic(Static.class) to mock the static class

In the following example we’re going to mock the static method max from Java’s Math class. We’re manipulating the max method to return the lower value instead of the higher value :)

The full test looks like this package com.hascode.tutorial ; import static org. mockito . Mockito . when ; import junit.framework.Assert ; import org.junit.Test ; import org.junit.runner.RunWith ; import org.powermock.api.mockito.PowerMockito ; import org.powermock.core.classloader.annotations.PrepareForTest ; import org.powermock.modules.junit4.PowerMockRunner ; @RunWith ( PowerMockRunner. class ) @PrepareForTest ( Math . class ) public class StaticClassExample { @Test public void testMockStatic ( ) { PowerMockito. mockStatic ( Math . class ) ; when ( Math . max ( 1 , 5 ) ) . thenReturn ( 1 ) ; // this is soo wrong ;) Assert . assertEquals ( 1 , Math . max ( 1 , 5 ) ) ; } }

Troubleshooting / Common Mistakes

“org.mockito.exceptions.base.MockitoException: Cannot mock/spy class java.lang.StringBuffer Mockito cannot mock/spy following: – final classes – anonymous classes – primitive types” -> You can’t mock final or static classes (without using PowerMock)

You can’t mix matchers with other non-matcher arguments in verification or stub methods

With Mockito 2 it’s possible to mock static or final classes without using external tools like PowerMock.

Follow these simple steps to upgrade to Mockito 2 and activate mocking final and static classes via the plugin SPI:

1) Upgrade to Mockito 2 by adding the following dependency to your pom.xml:

<dependency > <groupId > org.mockito </groupId > <artifactId > mockito-core </artifactId > <version > 2.10.0 </version > <scope > test </scope > </dependency >

2) Create a file named org.mockito.plugins.MockMaker in the directory src/test/resources/mockito-extensions/

3) Add the following content to this file: mock-maker-inline

Now mocking final or static classes should not be a problem.

Download Tutorial Sources

The tutorial’s source are available for download at Bitbucket.org or – if Mercurial is installed just do

hg clone https: // hascode @ bitbucket.org / hascode / hascode-tutorials

Resources

2017-10-03: Examples for mocking static or final classes with Mockito 2 added.

Examples for mocking static or final classes with Mockito 2 added. 2015-03-21: Formatting optimized.

Tags: bdd, easymock, hamcrest, jmock, junit, mock, mock injection, mocking, mockito, powermock, stub, stubbing, tdd, testing, unit test