当前位置: 首页 > 面试题库 >

测试自定义插件portlet:BeanLocatorException和事务回滚以进行服务测试

汝墨一
2023-03-14
问题内容

我的问题:

  1. 我可以成功测试CRUD服务的运行情况。我在@Before [setUp()]上执行插入操作,并在@After [tearDown()]上进行相同数据删除操作,但今后,我需要支持事务处理,而不是编写用于插入和删除的代码。

  2. 我可以成功获取实体的单个记录,但是当我触发搜索查询或尝试获取多个实体时,我得到:

com.liferay.portal.kernel.bean.BeanLocatorException:尚未为Servlet上下文MyCustom-
portlet设置BeanLocator

我的环境

  • 与Tomcat捆绑在一起的Liferay 6.0.5 EE

  • 使用Junit4的带有Liferay IDE 1.4的Eclipse Helios

  • 我正在我的测试,在Eclipse本身“蚁族”的命令,但不是通过打字Alt+ Shift+ XT

如果我对如何在JUnit上使用事务(或者至少对它在liferay中的工作方式有一些了解)以及如何解决BeanLocatorException(或至少为什么将其抛出)有一些想法,那将非常有帮助。

任何帮助将不胜感激。


问题答案:

我用于JUnit测试PortalBeanLocatorUtil.setBeanLocator(...)Mockito 框架,并通过-methode
注入服务。我认为这显然是通过弹簧配置来实现的。在这里,您有完整的示例如何使用它。这个例子很简单,所以很好,因为这种方法简单易懂。

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手动创建模拟类。

使用PowerMock的方法

使用PowerMock可以退位,BeanLocator因为PowerMock允许覆盖静态方法。这是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;
    }

}

在这里,您发现了带有Mockito和JUnit的PowerMock
1.4.12,其中包括依赖项http://code.google.com/p/powermock/downloads/detail?name=powermock-
mockito-
junit-1.4.12.zip&can=2&q=



 类似资料:
  • 测试将创建的数据保存在H2测试数据库中,随后的测试在测试套件中执行时将失败。 我如何用事务绕过类的所有测试,并在类的所有测试执行后回滚所有数据库修改?

  • 问题内容: 我正在运行一个简单的JUnit测试,又是一个应用程序DAO。问题是我总是得到: JUnit测试是: 如你所见,我明确声明不回滚此方法。 Spring JUnit支持是否总是将rollback设置为true? 问题答案: 它应该可以正常工作,就像你期望的那样,但是可能是你在被测类中打开了另一个事务,或者某个地方有其他功能/或错误。 顺便说一句,这个注释应该是足够的:

  • 我正在努力做一个工作junit测试,以回滚在骆驼路由过程中发生的操作。 我有一个骆驼路线设置,可以监听目录。它需要一个csv文件。当csv文件出现时,它会创建新的SearchAnalytics数据。它会在csv文件中的每一行向表中添加新行。 我放的默认的Spring事务方法似乎不适用于骆驼路由上发生的操作。 下面的代码可以工作。但是它会永久保存数据,并且不会回滚插入。这意味着测试只会通过一次,除非

  • 我有一个自定义任务定义来运行每个测试具有特殊设置的特定测试文件。我的任务定义如下: 现在,此设置中的一些测试是不可靠的,我尝试再次运行它们,如下所示: 我编写了一个测试类,第一次总是失败,第二次总是成功: 不幸的是,测试只执行一次,整个测试套件失败。我可以使用中所述的自定义规则成功运行测试https://stackoverflow.com/a/55178053/6059889 有没有办法将测试重试

  • 迁移工作得很好,但事务根本不起作用。 我尝试公开我的设置: 运行在docker容器中的MariaDB 10.1(我已经证明了测试中使用的所有表都在InnoDB中,因此支持事务处理) 基测试类正在使用 我尝试了一个单独的连接与一起进行测试,并使用默认连接进行测试。事务也不起作用