Unit Testing and Integration Testing for service builder with Liferay DXP/ 7.0 CE

Unit testing and Integration Testing for service builder is one of the most searchable content across internet. I have found many forums, posts, wiki and even github codes but none of them seems to be working with Liferay DXP (or Liferay 7 CE) version.

 

Till Liferay 6.2 version, service builder always packaged as portlet which implies that it has access to portlet container. Also, the api and service layers both were part of one package. Since Liferay DXP onwards service builder contains only api and service layer. We can create web layer to embed portlet within service builder but its not available by default.

Unit Testing with Liferay 6.2 describe the above statement.

 

There are many test frameworks which Liferay supports i.e. Mockito, Powermock, Easymock etc. This blog covers the unit testcases written using Mockito, as somehow Powermock was not working for me.

 

Unit Testing for service builder in Liferay DXP.

The very first step is to include following jars entries in service builder's service layer.

<!-- Test -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.portlet</groupId>
<artifactId>portlet-api</artifactId>
<version>2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>

 

NOTE:- The scope of these above dependency jars is test. Also, the version I have used for my POC is mentioned below.

 
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<powermock.version>1.5.6</powermock.version>
<org.springframework-version>4.1.1.RELEASE</org.springframework-version>
<liferay.version>7.0.0</liferay.version>
</properties>
 
@RunWith(MockitoJUnitRunner.class) is used for class annotation.
 
Before starting with mocking of objects, we have to analyze which all services are called inside the actual method for which we are writing JUnit Tescase.
 
Make service implementation class object as datamember.
 
AssignmentLocalServiceImpl impl = new AssignmentLocalServiceImpl();
 
For every service call made inside actual method, mock the service object and set the expected behaviour of the service method return value.
 
// Mock counterLocalService
CounterLocalService counterLocalService = Mockito.mock(CounterLocalService.class);
Mockito.when(counterLocalService.increment(Assignment.class.getName())).thenReturn(ASSIGNMENT_ID);
impl.setCounterLocalService(counterLocalService);
 
NOTE:- The last LoC mentioned above is setting the mocked service object in service implementation datamember object. This ensures the final result which will be asserted.
 
Now, lets say service layer has below code.
 
User user = userLocalService.getUser(userId);
assignment.setUserName(user.getFullName());
 
In this case, userLocalService returns User object which is further used for other functionality. So, we have to mock not just userLocalService but before that we have to mock User class as well. Hence the code will look like this.
 
// Mock User object to be used/returned by userLocalService
User user = Mockito.mock(User.class);
user.setUserId(USER_ID);
user.setFirstName("Liferay");
user.setLastName("Consultant");
Mockito.when(user.getFullName()).thenReturn(USER_NAME);
 
// Mock userLocalService
UserLocalService userLocalService = Mockito.mock(UserLocalService.class);
Mockito.when(userLocalService.getUser(USER_ID)).thenReturn(user);
impl.setUserLocalService(userLocalService);
 
The datamembers for above code are as follows.
private static String USER_NAME = "Liferay Consultant";
private static long USER_ID = 20164L;
 
Create serviceContext which is used by service builder. We can create serviceContext object since we have included javax.portlet dependency in our project.
 
private ServiceContext getServiceContext() {
 
// create ServiceContext object
ServiceContext serviceContext = new ServiceContext();
serviceContext.setCompanyId(COMPANY_ID);
serviceContext.setScopeGroupId(GROUP_ID);
serviceContext.setUserId(USER_ID);
return serviceContext;
}
 
Now at last mock and set service layer methods like CRUD operation or whatever it is.
 
// Mock assignmentLocalService
AssignmentLocalService assignmentLocalService = Mockito.mock(AssignmentLocalService.class);
Mockito.when(assignmentLocalService.createAssignment(ASSIGNMENT_ID)).thenReturn(assignment);
impl.setAssignmentLocalService(assignmentLocalService);
 
We can assert this value as below.
 
Assert.assertNotNull(impl.addAssignment(createAssignment(), getServiceContext()));
 
Here createAssignment() method returns assignment object.
 
private Assignment createAssignment() {
 
// Mock assignment object
Assignment assignment = Mockito.mock(Assignment.class);
assignment.setNew(true);
assignment.setPrimaryKey(ASSIGNMENT_ID);
assignment.setUuid("efef3911-e3cb-bd00-3e35-960359d0b936");
assignment.setCompanyId(COMPANY_ID);
assignment.setAssignmentId(ASSIGNMENT_ID);
assignment.setGroupId(GROUP_ID);
assignment.setCreateDate(DateUtil.newDate());
assignment.setUserId(USER_ID);
assignment.setUserName(USER_NAME);
return assignment;
}
 
NOTE:- The above mentioned code can be found in github location.
 

Integration Testing for service builder in Liferay DXP.

There is already good detailed example mentioned in Liferay developer's documentation. 

https://dev.liferay.com/develop/tutorials/-/knowledge_base/7-0/arquillian-extension-for-liferay-example

 

Courtesy to Thiago and Sampsa.

Blogs