【问题标题】:Junit test - com.liferay.portal.kernel.bean.BeanLocatorException: BeanLocator has not been setJunit 测试 - com.liferay.portal.kernel.bean.BeanLocatorException:尚未设置 BeanLocator
【发布时间】:2013-10-08 19:34:35
【问题描述】:
public class CustomServiceImplTest extends TestCase{

    ApplicationContext ac;

    private BeanLocator mockBeanLocator;

    @Test
    public void testCreateCategory() throws Exception {

        CustomService  customService = (CustomService) ac.getBean("customService");
        customService.CreateCategory();
    }

    @Before
    public void setUp()
    {
        mockBeanLocator = Mockito.mock(BeanLocator.class);
        PortalBeanLocatorUtil.setBeanLocator(mockBeanLocator);
        CompanyLocalServiceUtil mockCompanyLocalService = Mockito.mock(CompanyLocalServiceUtil.class);
        ac = CustomSpringUtils.loadApplicationContext(new String[] { ""/applicationContext-Services.xml" });
    }   
}

我正在使用基本的 JUnit 4,并在上面创建了扩展 TestCase 的测试类。

我得到的异常如下:

java.lang.NullPointerException  at com.liferay.portal.service.CompanyLocalServiceUtil.getCompanyByWebId(CompanyLocalServiceUtil.java:498)

下面的方法customService.CreateCategory();调用了 Lifery util 方法,例如 CompanyLocalServiceUtil.getCompanyByWebId 等。

请任何人对此有所了解。非常感谢任何帮助。

我需要在 spring 配置文件中提供 Liferay DS 信息吗?或

有什么办法可以将数据存根吗?
我正在尝试在 Liferay 实体类之一上测试 ADD 操作 -

MBCategoryLocalServiceUtil.addCategory(...)

【问题讨论】:

  • 能否提供CompanyLocalServiceUtil的源码?我找不到任何超过 300 行的源代码。干杯
  • public static CompanyLocalService getService() { if (_service == null) { _service = (CompanyLocalService)PortalBeanLocatorUtil.locate(CompanyLocalService.class.getName()); ReferenceRegistry.registerReference(CompanyLocalServiceUtil.class, "_service");MethodCache.remove(CompanyLocalService.class); }返回_服务; }private 静态 CompanyLocalService _service; // 由于空间限制,我没有提供 setService 方法。

标签: java spring junit liferay


【解决方案1】:

您必须在CompanyLocalServiceUtil 中注入/模拟CompanyLocalService 类。 Liferay 的做法是:

CompanyLocalService service = ..... // mock;
new CompanyLocalServiceUtil().setService(service);

setService 是一个实例方法,但为静态字段赋值。不要问我为什么要这样实现和设计。

【讨论】:

  • mockBeanLocator = Mockito.mock(BeanLocator.class); PortalBeanLocatorUtil.setBeanLocator(mockBeanLocator); CompanyLocalService mockCompanyLocalService = Mockito.mock(CompanyLocalService.class); CompanyLocalServiceUtil mockCompanyLocalServiceUtil = Mockito.mock(CompanyLocalServiceUtil.class); mockCompanyLocalServiceUtil.setService(mockCompanyLocalService); ac = CustomSpringUtils.loadApplicationContext(new String[] { ""/applicationContext-Services.xml" }); } 我试过了,但服务仍然为空。
  • 不要模拟*Util类,只模拟*Service并将其注入CompanyLocalServiceUtil
  • 是的,通过实例化 *Util 然后注入模拟 *Service 来摆脱空指针,但我确实有一堆 Liferay 实体调用(公司、用户、组、类别、角色、资源、权限)在一个方法中。我不确定测试我的自定义服务方法,这是一个好主意,值得以这种方式进行并进行模拟。我正在考虑注入 Liferay 的所有依赖 jar,spring xml 文件,所以我不需要模拟任何数据。
  • 使用数据库和实物是你应该尝试的最后一个。我在考虑可以使用Mockito 创建的partial mock。但是要使其工作,模拟方法必须是公共的或受保护的,不能模拟私有方法。您可以here 阅读更多关于子类和覆盖与部分模拟的信息。
  • setService 在 Liferay 6.2 中已被弃用
猜你喜欢
  • 1970-01-01
  • 2016-01-12
  • 1970-01-01
  • 2018-03-09
  • 2020-09-10
  • 1970-01-01
  • 1970-01-01
  • 2017-03-09
  • 1970-01-01
相关资源
最近更新 更多