Thursday, April 25, 2013

JUnit Test-Cases to test Liferay Portlet Service Layer

Configuration Steps:

  1. Create a folder named 'test' withing the project and add it as a source folder to have the test classes and maintain it separate rather than mixing with the portlet source codes.
  2. Create a 'PortletHibernateTestConfiguration' with the below lines of code.

public class PortletHibernateTestConfiguration extends PortalHibernateConfiguration {

protected ClassLoader getConfigurationClassLoader() {
return this.getClass().getClassLoader();
}

protected String[] getConfigurationResources() {
return PropsUtil.getArray(PropsKeys.HIBERNATE_CONFIGS);
}
}

  1. Create a 'portal-ext.properties' file directly under the 'test' folder using the below configurations as reference.
jdbc.default.driverClassName=com.mysql.jdbc.Driver
jdbc.default.url=jdbc:mysql://localhost/liferay6ce?characterEncoding=UTF-8
jdbc.default.username=root
jdbc.default.password=root

hibernate.cache.use_query_cache=false
hibernate.cache.use_second_level_cache=false
hibernate.cache.use_minimal_puts=false
hibernate.cache.use_structured_entries=false
ehcache.portal.cache.manager.jmx.enabled=false

liferay.home=D:/liferay-portal-6.1.0-ce-ga1
resource.repositories.root=D:/liferay-portal-6.1.0-ce-ga1/tomcat-7.0.23/webapps/ROOT

# Disable the scheduler for Unit testing
scheduler.enabled=false

hibernate.configs=\
META-INF/portal-hbm.xml,\
META-INF/portlet-hbm.xml,\
META-INF/portlet-orm.xml

  1. Create a 'META-INF' folder under the 'test' folder and create a 'hibernate-spring.xml' within it using the below code (Note: The PortalHibernateConfiguration class is replaced with our own implementation).

<?xml version="1.0" encoding="UTF-8"?>
<beans
default-destroy-method="destroy"
default-init-method="afterPropertiesSet"
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
>
<bean id="liferayHibernateSessionFactory" class="com.test.PortletHibernateTestConfiguration">
<property name="dataSource" ref="liferayDataSource" />
</bean>
<bean id="liferaySessionFactory" class="com.liferay.portal.dao.orm.hibernate.SessionFactoryImpl">
<property name="sessionFactoryClassLoader">
<bean class="com.liferay.portal.kernel.util.PortalClassLoaderUtil" factory-method="getClassLoader" />
</property>
<property name="sessionFactoryImplementor" ref="liferayHibernateSessionFactory" />
</bean>
<bean id="liferayTransactionManager" class="com.liferay.portal.spring.transaction.TransactionManagerFactory" factory-method="createTransactionManager">
<constructor-arg ref="liferayDataSource" />
<constructor-arg ref="liferayHibernateSessionFactory" />
</bean>
<bean id="hibernateStatisticsService" class="com.liferay.portal.dao.orm.hibernate.jmx.HibernateStatisticsService">
<property name="sessionFactory" ref="liferaySessionFactory" />
</bean>
<bean id="com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil" class="com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil">
<property name="dynamicQueryFactory">
<bean class="com.liferay.portal.dao.orm.hibernate.DynamicQueryFactoryImpl" />
</property>
</bean>
<bean id="com.liferay.portal.kernel.dao.orm.OrderFactoryUtil" class="com.liferay.portal.kernel.dao.orm.OrderFactoryUtil">
<property name="orderFactory">
<bean class="com.liferay.portal.dao.orm.hibernate.OrderFactoryImpl" />
</property>
</bean>
<bean id="com.liferay.portal.kernel.dao.orm.ProjectionFactoryUtil" class="com.liferay.portal.kernel.dao.orm.ProjectionFactoryUtil">
<property name="projectionFactory">
<bean class="com.liferay.portal.dao.orm.hibernate.ProjectionFactoryImpl" />
</property>
</bean>
<bean id="com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil" class="com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil">
<property name="propertyFactory">
<bean class="com.liferay.portal.dao.orm.hibernate.PropertyFactoryImpl" />
</property>
</bean>
<bean id="com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil" class="com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil">
<property name="restrictionsFactory">
<bean class="com.liferay.portal.dao.orm.hibernate.RestrictionsFactoryImpl" />
</property>
</bean>
</beans>


  1. Similarly add a 'counter-spring.xml' to the 'META-INF' folder with the below codes.

<?xml version="1.0" encoding="UTF-8"?>

<beans
default-destroy-method="destroy"
default-init-method="afterPropertiesSet"
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
>
<bean id="counterDataSource" class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
<property name="targetDataSource">
<bean class="com.liferay.portal.dao.jdbc.util.DataSourceFactoryBean">
<property name="propertyPrefixLookup" value="counter.jdbc.prefix" />
</bean>
</property>
</bean>
<bean id="com.liferay.counter.service.CounterLocalService" class="com.liferay.counter.service.impl.CounterLocalServiceImpl" />
<bean id="com.liferay.counter.service.persistence.CounterPersistence" class="com.liferay.counter.service.persistence.CounterPersistenceImpl" parent="basePersistence">
<property name="dataSource" ref="counterDataSource" />
</bean>
<bean id="com.liferay.counter.service.persistence.CounterFinder" class="com.liferay.counter.service.persistence.CounterFinderImpl" parent="basePersistence">
<property name="dataSource" ref="counterDataSource" />
</bean>
</beans>

  1. Copy the files portlet-hbm.xml, portlet-orm.xml & portlet-spring.xml from 'docroot/WEB-INF/src/META-INF' folder to your 'test/META-INF' folder.
  2. Rename the copied 'portlet-spring.xml' to 'ext-spring.xml'.
  3. Now create a Test Class extending the JUnit TestCase class and within the setUp() method, add the below code snippets to initialize the Spring-Hibernate context and get the Service classes initialized and linked to the back-end DB.
super.setUp();
InitUtil.initWithSpring();
PortletBeanLocatorUtil.setBeanLocator(ClpSerializer.getServletContextName(), PortalBeanLocatorUtil.getBeanLocator());

  1. It can be then continued with code to obtain the service as shown below.
userService = UserLocalServiceUtil.getService();
employeeService = EmployeeLocalServiceUtil.getService();

  1. Start writing your test cases and proceed with the usual way in executing them. If any memory error occurs, add the below VM arguments to the JUnit run configuration.

-Xms256m -Xmx512m -XX:PermSize=128M -XX:MaxPermSize=256m

Steps to run JUnit test through Liferay Ant Script:

Follow the below steps to run the JUnit test through the ANT script.
  1. Replace the below code of 'build-common.xml' from Liferay plugin-sdk
<path id="test.classpath">
<path refid="plugin.classpath" />
<fileset dir="${app.server.lib.portal.dir}" includes="commons-io.jar" />
<fileset dir="${project.dir}/lib" includes="junit.jar" />
<pathelement location="test-classes" />
</path>
with
<path id="test.classpath">
<path refid="plugin.classpath" />
<fileset dir="${app.server.lib.portal.dir}" includes="*.jar" />
<fileset dir="${project.dir}/lib" includes="junit.jar" />
<pathelement location="test-classes" />
</path>

  1. Similarly add additional jvm memory arguments to the 'junit' tag of the 'test' target of the 'build-common-plugin.xml' which is highlighted in bold. This is to avoid the Out of Memory error while running the test cases.
<junit dir="${project.dir}" fork="on" forkmode="once" printsummary="on">
<jvmarg line="${junit.debug.jpda}" />
<jvmarg value="-Xms256m" />
<jvmarg value="-Xmx512m" />
<jvmarg value="-XX:PermSize=128m" />
<jvmarg value="-XX:MaxPermSize=256m" />
<jvmarg value="-Duser.timezone=GMT" />
<jvmarg value="-Dexternal-properties=${test.properties}" />
<classpath refid="test.classpath" />
<formatter type="brief" usefile="false" />
<formatter type="xml" />
<batchtest todir="test-results">
<fileset dir="test-classes" includes="**/*Test.class" />
</batchtest>
</junit>

3 comments:

  1. Hi
    I tried this example but getting following error with LE 6.1 CE

    Caused by: java.lang.NullPointerException
    at com.liferay.portal.kernel.spring.util.SpringFactoryUtil.newBean(SpringFactoryUtil.java:42)

    any clue ??

    ReplyDelete
  2. Respect and that i have a neat provide: How Long Does House Renovation Take house repair near me

    ReplyDelete