
How to use JUnit to test service in portlets
Introduction
There are lots of articles in the internet to explain how to use JUnit to test our own portlets. However, after reading them, I still had lots of issues to run Unit test case. After trying a lot, it is finally successful. To make everyone can play around with it. I will share all necessary information you need to archieve this. By the way, the Eclipse is the IDE. Any feedback or feedback will be appreciated! :)
Steps
1. Create and build the basic portlets with the service.xml:
<service-builder package-path="com.jack">
<author>jacksun</author>
<namespace>jn</namespace>
<entity name="JunitTable" local-service="true">
<column name="id_" type="long" primary="true"></column>
<column name="name" type="String"></column>
<finder return-type="JunitTable" name="id_name">
<finder-column name="id_"></finder-column>
<finder-column name="name"></finder-column>
</finder>
</entity>
</service-builder>
2. To seperate testing code and source code, you can create another source folder, called testing for example. In this folder, create your own test case java class, here we call JunitTableLocalServiceImplTest:
package com.jack.service;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.liferay.portal.kernel.test.TestCase;
import com.liferay.portal.model.User;
import com.liferay.portal.service.UserLocalService;
import com.liferay.portal.service.UserLocalServiceUtil;
import com.liferay.portal.util.InitUtil;
public class JunitTableLocalServiceImplTest extends TestCase {
private JunitTableLocalService jts;
private UserLocalService userService;
@Before
protected void setUp() {
try{
System.out.println(">>>SET UP");
//init the application context and beans for Spring.
InitUtil.initWithSpring();
//Get the service for testing
jts = JunitTableLocalServiceUtil.getService();
//Test LR services
userService = UserLocalServiceUtil.getService();
super.setUp();
}catch(Exception ex){
ex.printStackTrace();
fail("Init failed...");
}
}
@After
protected void tearDown() throws Exception {
System.out.println(">>>TEAR DOWN");
jts = null;
userService = null;
super.tearDown();
}
@Test
public void testFindById(){
long id = 1001l;
try {
//Test own portlets
String userName = jts.getJunitTable(id).getName();
System.out.println(">>>>>my own username: " + userName);
assertEquals("jack", userName);
//Reading LR objects
List<User> users = userService.getUsers(-1, -1);
System.out.println("Number of User:"+ users.size());
for(User user : users){
System.out.println("User: " + user.getFullName());
}
} catch (Exception e) {
e.printStackTrace();
fail("Junit Find By Id failed --- ID: " + id);
}
}
}
3. To make sure the needed class can be found - InitUtil, you need to include the LR library into your project. The path should be: tomcat_home/webapps/ROOT/WEB-INF/lib.
4. You need to create another java class to replace the PortletHibernateConfiguration, here we call it PortletHibernateTestConfiguration and put into some package, here we put into com.jack.service.persistence package:
package com.jack.service.persistence;
import com.liferay.portal.kernel.util.PropsKeys;
import com.liferay.portal.kernel.util.PropsUtil;
import com.liferay.portal.spring.hibernate.PortletHibernateConfiguration;
public class PortletHibernateTestConfiguration extends
PortletHibernateConfiguration {
protected ClassLoader getConfigurationClassLoader() {
System.out.println(">>>>jack configuration hibernate");
return this.getClass().getClassLoader();
}
protected String[] getConfigurationResources() {
String[] configs = PropsUtil.getArray(PropsKeys.HIBERNATE_CONFIGS);
for(String config : configs){
System.out.println(config);
}
return configs;
}
}
5. Write one portal-ext.properties file and put it into src folder path. e.g. docroot/WEB-INF/src/, especially the "META-INF/portlet-hbm.xml" in the file, if you didn't have it, it will throw exception tell you your hibernate entity cannot be found! Double check the following attributes and make your adjustment.
jdbc.default.driverClassName=com.mysql.jdbc.Driver
jdbc.default.url=jdbc:mysql://localhost/lfportal?useUnicode=true&characterEncoding=UTF-8&useFastDateParsing=false
jdbc.default.username=root
jdbc.default.password=123
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
# Disable the scheduler for Unit testing
ehcache.portal.cache.manager.jmx.enabled=false
value.object.listener.com.liferay.portal.model.LayoutSet=
resource.repositories.root=C:/LR/liferay-portal-6.0.6/tomcat-6.0.29/webapps/ROOT
# Disable the scheduler for Unit testing
scheduler.enabled=false
hibernate.configs=\
META-INF/mail-hbm.xml,\
META-INF/portal-hbm.xml,\
META-INF/ext-hbm.xml,\
META-INF/portlet-hbm.xml
6. Write your own Spring config file and modify some auto-created spring files. Our own spring file should be named as ext-spring.xml and the three xml files I changed are: hibernate-spring.xml, infrastructure-spring.xml and portlet-spring.xml. However, I think even not modify those three files, it should also work.
And these files need to be put into META-INF folder under your src folder. Double check the following attributes and make your adjustment.
ext-spring.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans default-destroy-method="destroy" default-init-method="afterPropertiesSet"
xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean
class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy"
id="liferayDataSource">
<property name="targetDataSource">
<bean class="com.liferay.portal.dao.jdbc.util.DataSourceFactoryBean">
<property name="propertyPrefix" value="jdbc.default.">
</property>
</bean>
</property>
</bean>
<bean id="basePersistence" abstract="true">
<property name="dataSource" ref="liferayDataSource" />
<property name="sessionFactory" ref="liferaySessionFactory" />
</bean>
<bean id="com.jack.service.JunitTableLocalService" class="com.jack.service.impl.JunitTableLocalServiceImpl" >
</bean>
<bean id="com.jack.service.JunitTableLocalServiceUtil" class="com.jack.service.JunitTableLocalServiceUtil">
<property name="service" ref="com.jack.service.JunitTableLocalService" />
</bean>
<bean id="com.jack.service.JunitTableService" class="com.jack.service.impl.JunitTableServiceImpl">
</bean>
<bean id="com.jack.service.JunitTableServiceUtil" class="com.jack.service.JunitTableServiceUtil">
<property name="service" ref="com.jack.service.JunitTableService" />
</bean>
<bean id="com.jack.service.persistence.JunitTablePersistence" class="com.jack.service.persistence.JunitTablePersistenceImpl" parent="basePersistence" />
<bean class="com.liferay.portal.spring.transaction.TransactionManagerFactory"
factory-method="createTransactionManager" id="liferayTransactionManager">
<constructor-arg ref="liferayHibernateSessionFactory">
</constructor-arg>
<constructor-arg ref="liferayDataSource">
</constructor-arg>
</bean>
<bean class="com.jack.service.persistence.PortletHibernateTestConfiguration"
id="liferayHibernateSessionFactory">
<property name="dataSource" ref="liferayDataSource">
</property>
</bean>
<bean class="com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil"
id="com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil">
<property name="dynamicQueryFactory">
<bean class="com.liferay.portal.dao.orm.hibernate.DynamicQueryFactoryImpl">
</bean>
</property>
</bean>
<bean class="com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil"
id="com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil">
<property name="restrictionsFactory">
<bean class="com.liferay.portal.dao.orm.hibernate.RestrictionsFactoryImpl">
</bean>
</property>
</bean>
<bean class="com.liferay.portal.kernel.util.InfrastructureUtil"
id="com.liferay.portal.kernel.util.InfrastructureUtil">
<property name="dataSource" ref="liferayDataSource">
</property>
<property name="transactionManager" ref="liferayTransactionManager">
</property>
</bean>
</beans>
hibernate-spring.xml:
<?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.jack.service.persistence.PortletHibernateTestConfiguration">
<property name="dataSource" ref="liferayDataSource" />
</bean>
<bean id="liferaySessionFactory" class="com.liferay.portal.dao.orm.hibernate.SessionFactoryImpl">
<property name="sessionFactoryClassLoader" ref="portletClassLoader" />
<property name="sessionFactoryImplementor" ref="liferayHibernateSessionFactory" />
</bean>
<bean
class="com.liferay.portal.spring.transaction.TransactionManagerFactory" factory-method="createTransactionManager" id="liferayTransactionManager">
<constructor-arg ref="liferayDataSource">
</constructor-arg>
<constructor-arg ref="liferayHibernateSessionFactory">
</constructor-arg>
</bean>
</beans>
infrastructure-spring.xml:
<?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 class="com.liferay.portal.kernel.util.InfrastructureUtil" id="com.liferay.portal.kernel.util.InfrastructureUtil">
<property name="dataSource" ref="liferayDataSource">
</property>
<property name="transactionManager" ref="liferayTransactionManager">
</property>
</bean>
<bean class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy" id="liferayDataSource">
<property name="targetDataSource">
<bean class="com.liferay.portal.dao.jdbc.util.DataSourceFactoryBean">
<property name="propertyPrefix" value="jdbc.default.">
</property>
</bean>
</property>
</bean>
</beans>
portlet-spring.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" default-destroy-method="destroy" default-init-method="afterPropertiesSet" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="com.jack.service.JunitTableLocalService" class="com.jack.service.impl.JunitTableLocalServiceImpl" >
</bean>
<bean id="com.jack.service.JunitTableLocalServiceUtil" class="com.jack.service.JunitTableLocalServiceUtil">
<property name="service" ref="com.jack.service.JunitTableLocalService" />
</bean>
<bean id="com.jack.service.JunitTableService" class="com.jack.service.impl.JunitTableServiceImpl">
</bean>
<bean id="com.jack.service.JunitTableServiceUtil" class="com.jack.service.JunitTableServiceUtil">
<property name="service" ref="com.jack.service.JunitTableService" />
</bean>
<bean id="com.jack.service.persistence.JunitTablePersistence" class="com.jack.service.persistence.JunitTablePersistenceImpl" parent="basePersistence" />
<bean class="com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil" id="com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil">
<property name="dynamicQueryFactory">
<bean class="com.liferay.portal.dao.orm.hibernate.DynamicQueryFactoryImpl">
</bean>
</property>
</bean>
<bean class="com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil" id="com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil">
<property name="restrictionsFactory">
<bean class="com.liferay.portal.dao.orm.hibernate.RestrictionsFactoryImpl">
</bean>
</property>
</bean>
</beans>
7. Now, you can run your test case in your IDE. If you met the error: PermGen space(OOM exception), you could run your test case as configuration and in the argument(VM) field input:
-server -Xms800m -Xmx800m -XX:PermSize=64M -XX:MaxNewSize=256m -XX:MaxPermSize=128m -Djava.awt.headless=true