Mockito is a Java-based framework for creating mock objects. It allows developpers to create mocks based on classes or interfaces, specify behaviour and return values for methods, and verify interactions.

This article introduces the use of Mockito in JUnit tests, to test object interactions, and shows mock creations, method stubbing, and verification of interactions.

Creation of mocks


Mocks can be created in 2 ways :

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

public class TestRobotRemoteControl{

    @Mock
    private Robot robotMock;

    @Before
    public void setUp(){
        // first way
        this.robotMock = mock( Robot.class );
        /* second way, creates mocks for all
        the @Mock annotated attributes of the class */
        MockitoAnnotations.initMocks( this );
    }

}

And that's it! Mock are quickly created and provide default comportement, methods return null, empty collections, false, or 0 depending on the return type of the method.
You can mock interfaces (nice for TDD and low-coupling) and concrete classes too.

Mockito also provides a JUnit test runner, that handles the @Mock initialization.

@RunWith(MockitoJUnit44Runner.class)
public class TestRobotRemoteControl{
    @Mock 
    private Robot robotMock;
}

Stubbing


Now that the mocks are created, we can specify stub methods.

@Before
public void setUp(){
    // getDirection() will return Direction.NORTH
    when(robotMock1.getDirection()).thenReturn(Direction.NORTH);
    // moveForward() takes an int in parameter and returns true
    when(robotMock1.moveForward(anyInt())).thenReturn(true);
    // when moveForward() is called with a 0 parameter, 
    // it returns false because the robot doesn't move...
    when(robotMock1.moveForward(0)).thenReturn(false);
    // turnTo takes any Direction in parameter
    when( robotMock1.turnTo( isA(Direction.class) ) )
        .thenReturn(true);

    doThrow( new IllegalArgumentException() )
        .when( robotMock ).turnTo( null );
}

The stubs are created using "when" and "thenReturn" methods. Stubs are specified with different arguments that can be hard coded (if the argument is well-known as in the moveForward(0) exemple), or with argument matchers ( as in moveForward(anyInt()) ). Mockito comes with built-in argument matchers (anyInt(), anyBoolean(), anyString()... ), and allows creation of custom matchers. Method stubs can also throw exceptions.

Verifying interactions


Now that we have a mocked Robot, we can test our RemoteControl. The following code creates a RemoteControl and attaches it to a Robot, then verifies that the methods of the Robot are correctly called.

@Test
public void testRemote(){  
    RemoteControl remote = new RemoteControl();
    remote.setControlling(robotMock);
 
    // This should make the robot move 1 step
    remote.pressForward();
    // This should make the robot turn to WEST direction
    // because it was facing NORTH
    remote.pressTurnLeft();
    // verifications
    verify( robotMock, times(1)).moveForward(1);
    verify( robotMock ).turnTo( Direction.WEST );
    verifyNoMoreInteractions(robotMock1);
}

The verify method takes 2 arguments : a mock, and a number of invocations.

Here, verify checks that the moveForward() method has been called on the robotMock with the parameter 1, and only once ( times(1) is an optionnal parameter ), and that the robot was told to turn to the west direction. The verifyNoMoreInteractions() method checks that no other method has been called on the mock.

The second argument of verify() can be an exact number ( times(1), times(3) ... ), never(), or atLeast(2), atMost(4)...

Conclusion


Mockito provides a simple way to write mocks, specify their behaviour with stubs, and then verify the interactions between objects. It can be very useful to write isolation tests, and to develop in TDD (Test Driven Development). You can concentrate on one class of the application without having to develop all its dependencies (by the way, it encourages low-coupling, great!).

1 comments :

Chalouati Hani said...

Thanks

Post a Comment