Thursday, September 6, 2012

Way to use Mockito mocks in TDD


Mockito  is one of the leading mocking framework. It provides us functionality to create stubs and verify the invocation count of any specific method during any specific action.

Mocking is preferred during unit testing, when we either do not have real objects available for testing or want to focus on testing our newly created functionality without worrying about dependency  instantiation.

We need to use below maven dependency to include mockito  in our project -
<dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-all</artifactId>
      <version>1.8.5</version>
 </dependency>
To see  the way to use mockito, we will take a real life scenario, where we have trade interface and a validation class which has utility methods to validate the trade. In this example we want to test that validation method isTradeValid() is working as expected. 

We will perform below steps to test it -
1.       Create a mock stub of Trade interface using mockito
2.       Specify what the stub should return if any specific function is called.
3.       Call the method under test ,which is isTradeValid() and assert to validate the result
4.       verify that during execution of method under test, which is isTradeValid()  , other methods are called only specific number of times.

The sample code is as mentioned below -
Trade.java
package mockito;

public interface Trade {

 public String getPrincipal();

 public String getCounterparty();

 public Integer getNotional();

}
Validation.java
package mockito;

public class Validation {

 public boolean isTradeValid(Trade trade) {
  return trade.getNotional() > 0 && trade.getPrincipal() != null
    && trade.getCounterparty() != null;
 }
}
ValidateionTest.java
package mockito;

import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;

import junit.framework.TestCase;

public class ValidateionTest extends TestCase {

 @Mock
 private Trade trade;
 private Validation validation;

 @Override
 protected void setUp() throws Exception {
  super.setUp();
  MockitoAnnotations.initMocks(this);
  validation = new Validation();
 }

 public void testValidTrade() {
  Mockito.when(trade.getPrincipal()).thenReturn("JP Morgan");
  Mockito.when(trade.getCounterparty()).thenReturn("Morgan Stanly");
  Mockito.when(trade.getNotional()).thenReturn(1000);
  assertTrue(validation.isTradeValid(trade));
  Mockito.verify(trade, Mockito.times(1)).getPrincipal();
  Mockito.verify(trade, Mockito.times(1)).getCounterparty();
  Mockito.verify(trade, Mockito.times(1)).getNotional();
 }

 public void testInvalidTradeWithoutCounterparty() {
  Mockito.when(trade.getPrincipal()).thenReturn("JP Morgan");
  Mockito.when(trade.getCounterparty()).thenReturn(null);
  Mockito.when(trade.getNotional()).thenReturn(1000);
  assertFalse(validation.isTradeValid(trade));
  Mockito.verify(trade, Mockito.times(1)).getPrincipal();
  Mockito.verify(trade, Mockito.times(1)).getCounterparty();
  Mockito.verify(trade, Mockito.times(1)).getNotional();
 }
}

Description and use of mock API used in ValidateionTest is as mentioned below -
1.       @mock  is used  to mark which references we want to be initialized with corresponding stubs.
2.       MockitoAnnotations.initMocks(this); is used to ask the class to process and initialize the references, associated with @mock, with corresponding stubs.
3.       Mockito.when(trade.getPrincipal()).thenReturn("JP Morgan"); is used to specify what value should the stub return on invocation of specific function.
4.       Mockito.verify(trade, Mockito.times(1)).getPrincipal(); is used to verify the number of invocation of specific fucntion.

This project can be downloaded from here

References - http://salilstock.blogspot.in/2011/04/creating-mock-objects-for-test-driven.html