Unit Testing the Service Layer in Seam

Posted on Friday, February 19, 2010

3


In our last post we discussed about how to unit test the DB layer in Seam. Let us see how easy it is to test the service layer now. When you are unit testing the service layer, then ideally you would only want to test the service layer. What that means is that we should not be doing an integration test which talks to the real dao’s. Instead, we should have the ability to mock any objects which the service layer interacts with so that we are just testing the business logic and nothing else.

This is where the combination of Mockito and SeamTest work very well. Let us see how.

Mockito would allow you to easily mock the other units that you do not want to test but your unit under test depends on them. SeamTest on the other hand allows you to inject the mocked objects into the unit under test using the setField method. Hence a simple test would look like this


@RunWith(MockitoJUnitRunner.class)
public class IkeManagerActionTest extends SeamTest {

 @Mock
 private IkeSessionDao ikeSessionDao;

 @Mock
 private IkeDao ikeDao;

 @Mock
 private FacesMessages facesMessages;

 @Mock
 private Ike ike;

 @Test
 public void createIke() {
 IkeManagerAction ikeManagerAction = new IkeManagerAction();

 setField(ikeManagerAction, "ikeDao", ikeDao);
 setField(ikeManagerAction, "facesMessages", facesMessages);
 ikeManagerAction.createIke(ike);

 verify(ikeDao, times(1)).createIke(ike);

 }

 @Test
 public void createIkeSession_WithMocks() {
 IkeManagerAction ikeManagerAction = new IkeManagerAction();

 IkeSession ikeSession = mock(IkeSession.class);

 setField(ikeManagerAction, "ikeSessionDao", ikeSessionDao);
 setField(ikeManagerAction, "facesMessages", facesMessages);
 ikeManagerAction.createIkeSession(ikeSession, ike);

 verify(ikeSessionDao, times(1)).createIkeSession(ikeSession, ike);
 }

There are other mocking frameworks like easymock, rmock etc that you might want to use but the syntax and english like verbose statements of mockito make it a frontrunner in the mocking frameworks. Look at the following code snippet


@RunWith(MockitoJUnitRunner.class)
public class ServiceInjectorTest extends SeamTest {

 private ServiceInjector serviceInjector;

 @Mock
 private User loggedInUser;

 @Mock
 private WebAppContextService webAppContextService;

 @Before
 public void setUp() {
 serviceInjector = new ServiceInjector();
 setField(serviceInjector, "webAppContextService", webAppContextService);
 setField(serviceInjector, "loggedInUser", loggedInUser);
 }

 @Test
 public void testCompanyServiceReturnedForUserC1() {
 CompanyServiceC1 companyServiceC1 = new CompanyServiceC1();
 when(loggedInUser.getUserType()).thenReturn(UserType.C1);
 when(webAppContextService.lookupBeanOrComponent("companyService"+UserType.C1)).thenReturn(companyServiceC1);
 Assert.assertEquals(serviceInjector.injectService("companyService"), companyServiceC1);
 }

 @Test
 public void testCompanyServiceReturnedForUserC2() {
 CompanyService companyService = new DemoCompanyService();
 when(loggedInUser.getUserType()).thenReturn(UserType.C2);
 when(webAppContextService.lookupBeanOrComponent("companyService"+UserType.C2)).thenReturn(null);
 when(webAppContextService.lookupBeanOrComponent("companyService")).thenReturn(companyService);
 Assert.assertEquals(serviceInjector.injectService("companyService"), companyService);
 }

}

Hence, as you would observe that unit testing the Service Layer is very easy in Seam.


Get in touch

Interested to know more about our JBoss Seam capabilities? Get in touch with us on seam@inphina.com

Posted in: Java