Showing posts with label Mockito. Show all posts
Showing posts with label Mockito. Show all posts

Tuesday, 12 July 2011

Specifying parameters for Mockito unit testing

Recently we faced a problem where we wanted to unit-test a service operation using mock objects for dependencies, but the objective of the test was to ensure the operation correctly instantiated an entity from the parameters so that it was ready to be persisted.


@Transactional
public User registerUser(Map<UIField,String> details) {
  User user = new User();
  List<UIField> identifierTypes = referenceDataService.
    getUserIdentifierTypeList();
  Set<UserDetail> userDetails = new HashSet<UserDetail>();
  Set<UserIdentifier> userIdentifiers = new   
    HashSet<UserIdentifier>();
  for(UIField key :details.keySet()) {   
    if(isIdentifierField(key,identifierTypes)) {            userIdentifiers.add(createUserIdentifier(key,
        details.get(key)));
    } else {
      userDetails.add(createUserDetail(key,details.get(key)));
    }
  }
  user.setUserIdentifiers(userIdentifiers);
  user.setUserDetails(userDetails);
  UserStatus status = referenceDataService.
    getUserStatus("REGISTERED");
  user.setUserStatus(status);
  return userService.createUser(user);
}
Listing 1

As listing 1 shows, the registerUser operation instantiates a User object and populates its properties using the parameters passed to the operation. Now we would like the unit-test to ensure this User instance is correctly constructed and its properties correctly populated so that the userService can persist the user. Listing 2 shows the unit-test.


@Test
public void testRegisterUser() {
//need a map of the data that is being submitted for registration.
  Map<UIField,String> data = new HashMap<UIField,String>();
  addUIField(data,"MSISDN","07987654321");
  addUIField(data,"Firstname","Joe");
  addUIField(data,"Lastname","Bloggs");        
  List<UIField> idFieldList = new ArrayList<UIField>();
  idFieldList.add(createUIField("MSISDN"));
     
  Mockito.when(referenceDataService.getUserIdentifierTypeList()).
    thenReturn(idFieldList);
  UserStatus userStatus = new UserStatus();
  userStatus.setValue("REGISTERED");

  Mockito.when(referenceDataService.getUserStatus("REGISTERED")).
    thenReturn(userStatus);
  registrationService.registerUser(data);            
  ArgumentCaptor<User> argument =
    ArgumentCaptor.forClass(User.class);

  Mockito.verify(userService).createUser(argument.capture());
  User user = argument.getValue();
  Assert.assertNotNull(user);

  Assert.assertEquals(user.getUserStatus().getValue(),"REGISTERED");
  Assert.assertEquals(1, user.getUserIdentifiers().size());
  Assert.assertEquals(2, user.getUserDetails().size());
}
 Listing 2

The userService and referenceDataService are mock objects which get injected into the RegistrationService. The concern was how to retrieve the user instance from the registerUser operation so that it can be inspected. For this, Mockito provides the ArgumentCaptor class and its use is highlighted in bold showing how to retrieve the User instance and then carry out further assertions.

Wednesday, 6 July 2011

Simple Example - Use of Mockito

Mockito is very helpful for junit testing, especially for the mocking the object. No need for having setters for injecting the mock object to the bean, mockito does it in very simple way. The following example will help to understand the use of mocking of injected bean.

Service:
public class UIConfigServiceImpl implements UIConfigService {

  @Autowired
  private UIConfigDAO uiConfigDAO;

  public List getUIConfigData(UIConfigType configType) {
    logger.debug("Inside UiConfigService");
    return uiConfigDAO.getUIConfigData(configType);
  }
}

Junit Test:
@RunWith(MockitoJUnitRunner.class) // Run the Junit with Mockito Junit Runner
public class UIConfigServiceTest {

  @InjectMocks // Inject Mock objects into the service. Mockito allows to inject beans where @Autowired is used without requiring setters.
  private UIConfigService uiConfigService = new UIConfigServiceImpl();

  @Mock // Creating a mock for injected object
  private UIConfigDAO mock;

  @Test
  public void testGetUIConfigData() {
    List list = new ArrayList();
    UserDetailType suc = new UserDetailType();
    list.add(suc);
    Mockito.when(mock.getUIConfigData(null)).thenReturn(list);
    List rv = uiConfigService.getUIConfigData(null);
    Assert.assertNotNull(rv);
    Assert.assertFalse(rv.isEmpty());
  }
}