Mockito Basics - Part 1


Mockito

Mockito is mocking framework for unit tests in Java. It facilities creating mock objects, configuring mock objects and assigning their behavior.


Mock Concepts

Mocks

When writing unit test, we want to test our code in isolation, we usually care about the code we are writing for certain class but the code might be using other classes and methods which we don’t want to test. Mocks are pretty much dummy objects you are introducing to substitute external classes you are working with. Mocks allows us to pretend as if we are dealing with the real class and mocks can be programmed to return whatever values we want and confirm whatever values are passed to them.

There are two common concepts you need to be familiar with when using Mocks.

Stubbing

Stubbing is the process of specifying behavior of the mock. It allows us to control response of the mocks. Generally stubbing is done by using when(...).thenReturn(....) or doReturn(...).when(...) methods.

Verification

Verification is the process of verifying behavior of the mock. Using verification how the mocks were interacted while running the test.

If you use Mockito in tests you typically:

  • Mock external dependencies and insert the mock into the code under the test.
  • Stub Mock Methods (if required)
  • Execute code under test.
  • Validate / Verify that the code executed correctly.

Adding Mockito to Project

Gradle Dependency

dependencies {
  testCompile group: 'org.mockito', name: 'mockito-core', version: '1.9.+'
}

Importing to Your Project

import org.junit.Test;
import org.mockito.Mockito;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

Mocking a class


//Mock Class
Iterator i = mock(Iterator.class);

//Mocking Using Annotations
@Mock
MyDatabase databaseMock;

Initializing Mock Objects

  • There are two ways to initialize mock objects

Using MockitoAnnotation.initMocks()

public class SampleMockTest(){

  @before
  public void init(){
    MockitoAnnotation.initMocks(this);
  }
}

Using MockitoJuniRunner.class

@RunWith(MockitoJuniRunner.class)
public class SampleMockTest(){

}

Configuring Mock

when(...).thenReturn(....) method chain can be used to specify the condition and the return value for a mock object.

Mockito.when(i.next()).thenReturn("Hello").thenReturn("World");

String result = i.next() + " " + i.next();
assertEquals("Hello World", result);

Verifying Calls on Mock Objects

Mockito keeps track of all the method call and their parameters to the mock object. Using Verify() method on the mock, you can verify if certain calls are made on the mock. This type of testing is called Behaviour Testing

MyClass test = Mockito.mock(MyClass.class);
when(test.getUniqueId()).thenReturn("1");

test.getUniqueId();
test.getUniqueId();

//Verification MethodCall
verify(test).getUniqueId();

//Verification Times
verify(test, atLeast(1)).getUniqueId();
verify(test, times(2)).getUniqueId();

Using Argument Matchers

//Using Matchers
when(c.compareTo(anyInt())).thenReturn(-1);

Examples


@Slf4j
public class MockitoBasics {

    @Mock
    Iterator<String> stringIterator;

    @Before
    public void setup(){
        log.info("Running Before Block");
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testBasicMockUsingWhenThen(){
        // Define Return Value for method next()
        when(stringIterator.next()).thenReturn("Hello").thenReturn("World");
        String result = stringIterator.next();
        assertEquals("Hello", result);

        // Use Mock in Test
        result = stringIterator.next();
        assertEquals("World", result);
    }


    @Test
    public void testReturnValueDependentOnMethodParameter(){
        Comparable c = mock(Comparable.class);
        //Return Value Based on Input
        when (c.compareTo("Mockito")).thenReturn(1);
        when(c.compareTo("Eclipse")).thenReturn(2);

        //Assert
        assertEquals(1, c.compareTo("Mockito"));

        //Assert
        assertEquals(2, c.compareTo("Eclipse"));
    }

    @Test
    public void testVerifyCallsOnMockObjects(){
        Comparable c = mock(Comparable.class);

        //Return Value Independent of Input Value
        when(c.compareTo(anyInt())).thenReturn(-1);

        //Assert
        assertEquals(c.compareTo(5), -1);
    }

    @Test
    public void testVerify(){
        //Create and Configure Mock
        MyClass test = Mockito.mock(MyClass.class);
        when(test.getUniqueId()).thenReturn(43);

        // Call Method
        test.getUniqueId();
        test.getUniqueId();

        // Verifying Number of Method Calls
        verify(test, times(2)).getUniqueId();
        verify(test, atLeast(1)).getUniqueId();
        verify(test, never()).getHome();

    }
}