测试自定义插件portlet:BeanLocatorException和Transaction roll-back用于服务测试 [英] Testing for custom plugin portlet: BeanLocatorException and Transaction roll-back for services testing
问题描述
我的问题:
- 我可以成功测试CRUD服务操作。我在@Before [setUp()]上插入
并在@After
[tearDown()]上删除相同数据但是我需要支持Transactions
而不是写入插入和删除的代码。 -
我成功获取了我的实体的单个记录但是当我触发搜索查询或尝试获取多个实体时,我得到:
- I can test successfully for CRUD services operation. I was doing an insert on @Before [setUp()] and delete of same data on @After [tearDown()] but going forward I would need to support Transactions rather than writing code for insert and delete.
I am successful in fetching single records of my entity but when I fire a search query or try to fetch more than one of my entities I get:
com.liferay.portal.kernel.bean.BeanLocatorException:尚未为servlet上下文设置BeanLocator MyCustom-portlet
com.liferay.portal.kernel.bean.BeanLocatorException: BeanLocator has not been set for servlet context MyCustom-portlet
我已按照以下部分链接设置Junit与Liferay:
I have followed some of the following links to set-up Junit with Liferay:
- Liferay wiki - How to use Junit to test Service in Portlets
- SO - Unit Testing in Liferay
- SO - Junit Testing DAOs rollback or Delete
我的环境
-
Liferay 6.0.5 EE与Tomcat捆绑
Liferay 6.0.5 EE bundled with Tomcat
Eclipse Helios与Liferay IDE 1.4使用Junit4
Eclipse Helios with Liferay IDE 1.4 using Junit4
我在eclipse中使用ant命令运行我的测试但不是通过键入 Alt + Shift + <
kbd> X , T 。
I am running my tests with "ant" command in eclipse itself but not through typing Alt+Shift+X, T.
如果我可以了解如何使用JUnit进行交易(或者至少有一些关于它如何在liferay中工作的想法)以及如何解决 BeanLocatorException
(或者至少为什么会被抛出)
It would be really helpful if I can get some idea as to how to go about using Transactions with JUnit (or at least some ideas as to how it works in liferay) and how to resolve the BeanLocatorException
(or at least why would it be thrown)
任何帮助将不胜感激。
推荐答案
我用于JUnit测试mockito框架并通过 PortalBeanL注入服务ocatorUtil.setBeanLocator(...)
-methode。我认为使用弹簧配置显然可以做到这一点。这里有完整的示例如何使用它。这个例子很好,因为这种方法很简单易懂。
I use for JUnit testing mockito framework and inject the services over PortalBeanLocatorUtil.setBeanLocator(...)
-methode. I think that is clearly as to do this with spring configuration. Here you have full example how it can be used. The example is shot and that is good so, because the approach is simple and understandable.
package mst.unittest.example;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.junit.Before;
import org.junit.Test;
import com.liferay.portal.kernel.bean.BeanLocator;
import com.liferay.portal.kernel.bean.PortalBeanLocatorUtil;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.model.User;
import com.liferay.portal.service.UserLocalService;
import com.liferay.portal.service.UserLocalServiceUtil;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
/**
* @author mark.stein.ms@gmail.com
*/
public class MyUserUtilTest {
private BeanLocator mockBeanLocator;
@Before
public void init() {
//create mock for BeanLocator, BeanLocator is responsible for loading of Services
mockBeanLocator = mock(BeanLocator.class);
//... and insert it in Liferay loading infrastructure (instead of Spring configuration)
PortalBeanLocatorUtil.setBeanLocator(mockBeanLocator);
}
@Test
public void testIsUserFullAge() throws PortalException, SystemException, ParseException {
//setup
SimpleDateFormat format = new SimpleDateFormat("yyyy_MM_dd");
Date D2000_01_01 = format.parse("2000_01_01");
Date D1990_06_30 = format.parse("1990_06_30");
UserLocalService mockUserLocalService = mock(UserLocalService.class);
User mockUserThatIsFullAge = mock(User.class);
when(mockUserThatIsFullAge.getBirthday()).thenReturn(D1990_06_30);
User mockUserThatIsNotFullAge = mock(User.class);
when(mockUserThatIsNotFullAge.getBirthday()).thenReturn(D2000_01_01);
//overwrite getUser(...) methode so that wir get mock user-object with mocked behavior
when(mockUserLocalService.getUser(1234567)).thenReturn(mockUserThatIsFullAge);
when(mockUserLocalService.getUser(7654321)).thenReturn(mockUserThatIsNotFullAge);
//load our mock-object instead of default UserLocalService
when(mockBeanLocator.locate("com.liferay.portal.service.UserLocalService")).thenReturn(mockUserLocalService);
//run
User userFullAge = UserLocalServiceUtil.getUser(1234567);
boolean fullAge = MyUserUtil.isUserFullAge(userFullAge);
//verify
assertTrue(fullAge);
//run
User userNotFullAge = UserLocalServiceUtil.getUser(7654321);
boolean notfullAge = MyUserUtil.isUserFullAge(userNotFullAge);
//verify
assertFalse(notfullAge);
}
}
class MyUserUtil {
public static boolean isUserFullAge(User user) throws PortalException, SystemException {
Date birthday = user.getBirthday();
long years = (System.currentTimeMillis() - birthday.getTime()) / ((long)365*24*60*60*1000);
return years > 18;
}
}
您也可以使用此方法mockito框架,那么你必须手动创建像 MockBeanLocator
这样的模拟类。
You can use this approach also without mockito framework, then you must create the mock-classes like MockBeanLocator
manually.
接近PowerMock
使用PowerMock,您可以放弃 BeanLocator
,因为PowerMock允许覆盖静态方法。这是与PowerMock相同的示例:
With PowerMock you can to abdicate BeanLocator
because PowerMock allows to override static methods. Here the same example with PowerMock:
package mst.unittest.example;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.model.User;
import com.liferay.portal.service.UserLocalServiceUtil;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
/**
* @author Mark Stein
*
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest(UserLocalServiceUtil.class)
public class LiferayAndPowerMockTest {
@Test
public void testIsUserFullAge() throws PortalException, SystemException, ParseException {
//setup
SimpleDateFormat format = new SimpleDateFormat("yyyy_MM_dd");
Date D2000_01_01 = format.parse("2000_01_01");
Date D1990_06_30 = format.parse("1990_06_30");
User mockUserThatIsFullAge = mock(User.class);
when(mockUserThatIsFullAge.getBirthday()).thenReturn(D1990_06_30);
User mockUserThatIsNotFullAge = mock(User.class);
when(mockUserThatIsNotFullAge.getBirthday()).thenReturn(D2000_01_01);
//overwrite getUser(...) by UserLocalServiceUtil methode so that wir get mock user-object with mocked behavior
PowerMockito.mockStatic(UserLocalServiceUtil.class);
when(UserLocalServiceUtil.getUser(1234567)).thenReturn(mockUserThatIsFullAge);
when(UserLocalServiceUtil.getUser(7654321)).thenReturn(mockUserThatIsNotFullAge);
//run
boolean fullAge = MySecUserUtil.isUserFullAge(1234567);
//verify
assertTrue(fullAge);
//run
boolean notfullAge = MySecUserUtil.isUserFullAge(7654321);
//verify
assertFalse(notfullAge);
}
}
class MySecUserUtil {
public static boolean isUserFullAge(long userId) throws PortalException, SystemException {
User user = UserLocalServiceUtil.getUser(userId);
Date birthday = user.getBirthday();
long years = (System.currentTimeMillis() - birthday.getTime()) / ((long)365*24*60*60*1000);
return years > 18;
}
}
在这里你找到了PowerMock 1.4.12 Mockito和JUnit包含依赖项 http://code.google.com/p/powermock/downloads/detail?name=powermock-mockito-junit-1.4.12.zip&can=2&q=
Here you found PowerMock 1.4.12 with Mockito and JUnit including dependencies http://code.google.com/p/powermock/downloads/detail?name=powermock-mockito-junit-1.4.12.zip&can=2&q=
这篇关于测试自定义插件portlet:BeanLocatorException和Transaction roll-back用于服务测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!