Thursday, June 16, 2016

Mocking of enum singleton class with PowerMock and Mockito

The earlier post Mocking with PowerMock and Mockito explains how to use the PowerMock for mocking of static classes. Another method of mocking with the PowerMock is the Whitebox class. It provides various utilities for accessing internals of a class. A singleton class which is implemented with enum singleton pattern, may be easily mocked with the Whitebox.setInternalState.

In the example below a singleton DAOFactory contains several DAO services as enum values. Each DAO service supports DB access to a particular DB entity.

The factory class:
public enum DAOFactory {
 USER_DAO(new UserDAO()), 
 SUPER_USER_DAO(new SuperUserDAO()),
 IMPORT_HISTORY_DAO(new ImportHistoryDAO()),
 IMPORT_SYNCH_TASKS_DAO(new ImportSynchTasksDAO()),
 ; 
 private Object dao; 
 private DAOFactory(Object dao) {
  this.dao = dao;
 } 
 public Object getService() {
  return this.dao;
 }
}
Example of a DAO service class:
public class UserDAO {
      public DbUser getById(int userId) {...}
      public DbUser getByEmail(String email) {...}        ...
}
An application gets an access to the DAO services API via DAOFactory.
DbUser dbUser = (UserDAO) DAOFactory.USER_DAO.getService().getByIdProcedure(userId);

For unit testing of the application code we need to mock the DB stuff. Namely, we should mock the DAO services.
The example shows a test, which mocks the service UserDAO:
@RunWith(PowerMockRunner.class)
@PrepareForTest({DAOFactory.class})
@PowerMockIgnore({"javax.management.*"})
public class TestController {
 
      @Mock
      protected DAOFactory fakeDbServiceFactory;
      @Mock
      protected UserDAO fakeDbUserService;
 
      @Test
      public void testUserOK() {
           // DB service mocking prior to test execution
           Whitebox.setInternalState(DAOFactory.class, "USER_DAO", fakeDbServiceFactory);
           when(fakeDbServiceFactory.getService()).thenReturn(fakeDbUserService);
           dbUser = createFakeDbUser();
           when(fakeDbUserService.getByEmail(Mockito.anyString())).thenReturn(dbUser);
           // test stuff ....
      }
      …
}

No comments :

About the author

My Photo
I trust only simple code and believe that code should be handsome. This is not a matter of technology, but professional approach, consolidated after years of software development. I enjoy to cause things working and feel very happy, when I manage to solve a problem.
Back to Top