Liferay portlet 的单元测试

发布于 2024-10-12 15:39:33 字数 269 浏览 4 评论 0原文

有谁知道如何为 Liferay portlet 运行单元测试?我发现了很多关于它的帖子(例如 http://agile-reflections.opnworks.com/2010/06/portlet-unit-testing-with-liferay-6.html),但仍然没有任何效果。

Does anyone know how to run unit tests for Liferay portlets? I have found a lot of posts about it (e.g. http://agile-reflections.opnworks.com/2010/06/portlet-unit-testing-with-liferay-6.html) but none works nonetheless.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

2024-10-19 15:39:33

这可能有点矫枉过正,但如果您正在寻找具有持续集成测试的企业方法,此博客提供了一个很好的示例:Liferay 上的持续集成:在 Tomcat 6 包上运行 Selenium 2 测试< /a>

This may be overkill, but if you're looking for an Enterprise approach with continuous integration testing, this blog gives a very good example: Continuous integration on Liferay: running your Selenium 2 tests on the Tomcat 6 bundle

北恋 2024-10-19 15:39:33

当使用 ServiceBuilder 时,单元测试 Liferay portlet 是相当复杂的。

原因是它生成相当繁重的服务,这些服务不仅包含对 Portlet 内的 Bean 的引用,甚至还包含对 ServiceBuilder 生成的 Portal Bean 的引用。

有一些工具,例如 InitUtil.init();这至少可以让您实例化和使用 ServiceBuilder 实体...但不是 EntityServices。为此,您必须使用 SpringUtil.loadContext();这需要

System.setProperty("external-properties", "testing.properties");

其中testing.properties包含:

spring.configs=META-INF/ext-spring.xml,\
            META-INF/base-spring.xml,\
            META-INF/dynamic-data-source-spring.xml,\
            META-INF/infrastructure-spring.xml,\
            META-INF/shard-data-source-spring.xml,\
            META-INF/hibernate-spring.xml,\
            META-INF/portlet-spring.xml

这些是要加载用于测试应用程序上下文的spring定义。一切都可以,但是 portlet-spring.xml 中的 bean 是那些包含对 Portal bean 定义(如 ResourceService、UserLocalService、CounterLocalService)引用的繁重服务,您甚至必须加载 META-INF/portal-spring.xml< /code> 相信我,这并不容易,因为你必须加载很多其他东西。

答案:

事实是,您很可能不需要对 portlet SB 服务进行单元测试,永远不需要。它们代表具有持久性和服务层的实体。一些不需要测试的东西。你只需要嘲笑他们并存根他们的方法,对吧?

对于模拟而言,junit 和集成测试的最佳方法不是在应用程序中使用 *LocalServiceUtil 静态类,因为它几乎是不可模拟的。

您只需要创建一个 Spring FactoryBean:

public class PortalFactoryBean implements FactoryBean {
    private Class type;

    public void setType(final Class type) {
        this.type = type;
    }

    @Override
    public Object getObject() throws Exception {
        return PortalBeanLocatorUtil.locate(type.getName());
    }

    @Override
    public Class getObjectType() {
        return type;
    }
}

public class PortletFactoryBean implements FactoryBean {
    private Class type;

    public void setType(final Class type) {
        this.type = type;
    }

    @Override
    public Object getObject() throws Exception {
        return PortletBeanLocatorUtil.locate(type.getName());
    }

    @Override
    public Class getObjectType() {
        return type;
    }
}

<bean id="somePortalBean" class="example.spring.PortalFactoryBean" lazy-init="true">
   <property name="type" value="com.liferay.some.util.SomeService"/>
</bean>

<bean id="somePortletBean" class="example.spring.PortletFactoryBean" lazy-init="true">
   <property name="type" value="com.example.SomeService"/>
</bean>

@Autowired
private SomeService somePortalBean;

为这个 portlet 编写单元/集成测试将非常容易,对吧?您只需创建一个用于测试的 spring 上下文并模拟这些服务:

使用 Service Builder 是值得的,但您必须具备一些 Spring 知识并使用它一段时间。然后它可以节省很多时间,因为它很容易维护。

Unit testing Liferay portlets is quite complicated when ServiceBuilder is utilized.

The reason is that it generates quite heavy services that contain references not only to beans within Portlet, but even to the Portal beans generated by ServiceBuilder.

There are tools like InitUtil.init(); that lets you at least instantiate and use ServiceBuilder entities... not EntityServices though. For that you'd have to use SpringUtil.loadContext(); that requires

System.setProperty("external-properties", "testing.properties");

where testing.properties contains :

spring.configs=META-INF/ext-spring.xml,\
            META-INF/base-spring.xml,\
            META-INF/dynamic-data-source-spring.xml,\
            META-INF/infrastructure-spring.xml,\
            META-INF/shard-data-source-spring.xml,\
            META-INF/hibernate-spring.xml,\
            META-INF/portlet-spring.xml

These are spring definitions to be loaded for testing application context. It all would be OK, but beans from portlet-spring.xml are those heavy services containing references to Portal bean definitions like ResourceService, UserLocalService, CounterLocalService and you would have to load even META-INF/portal-spring.xml and trust me, it's not that easy cause then you'd have to load quite a lot of other stuff.

THE ANSWER:

The truth is, that you most likely won't have to unit test portlet SB services, never. They represent entities with persistence and service layer around. Something that is not to be tested. You just have to mock them and stub their methods, right ?

And the best way for junit and integration testing as to mocking is not using *LocalServiceUtil static classes in your application, because it is almost unmockable.

You just need to create a Spring FactoryBean :

public class PortalFactoryBean implements FactoryBean {
    private Class type;

    public void setType(final Class type) {
        this.type = type;
    }

    @Override
    public Object getObject() throws Exception {
        return PortalBeanLocatorUtil.locate(type.getName());
    }

    @Override
    public Class getObjectType() {
        return type;
    }
}

public class PortletFactoryBean implements FactoryBean {
    private Class type;

    public void setType(final Class type) {
        this.type = type;
    }

    @Override
    public Object getObject() throws Exception {
        return PortletBeanLocatorUtil.locate(type.getName());
    }

    @Override
    public Class getObjectType() {
        return type;
    }
}

<bean id="somePortalBean" class="example.spring.PortalFactoryBean" lazy-init="true">
   <property name="type" value="com.liferay.some.util.SomeService"/>
</bean>

<bean id="somePortletBean" class="example.spring.PortletFactoryBean" lazy-init="true">
   <property name="type" value="com.example.SomeService"/>
</bean>

@Autowired
private SomeService somePortalBean;

Writing unit/integration tests for this portlet would be quite easy, right ? You just create a spring context for testing and you mock these services :

Using Service Builder is worth it, but you must have some Spring knowledge and play with it for some time. Then it spares a lot of time because it is easy to maintain.

拥抱影子 2024-10-19 15:39:33

您需要在类路径上有一些第三方库< /a>.

关键点是甚至在类路径上具有portal-impl.jar和其他门户依赖项,并具有InitUtil.initWithSpring(boolean);加载您在spring中的spring-ext.properties中指定的核心spring xml配置.congigs 财产,只提供您需要的服务。您可能不需要门户服务而只需要Portlet 服务,但这是一个问题,因为服务构建器生成的Portlet 服务使用门户服务。

使用服务构建器只需要对 spring 和类加载有很好的了解。

但在此之前您需要了解基础设施。需要很多技巧......比如

BeanLocator beanLocator = new BeanLocatorImpl(PortalClassLoaderUtil.getClassLoader(), ac);
PortletBeanLocatorUtil.setBeanLocator("portlet", beanLocator);

You need to have some third party libraries on classpath.

THe key point is having even portal-impl.jar and other portal dependencies on classpath and having InitUtil.initWithSpring(boolean); load up core spring xml configs that you specify in spring-ext.properties in spring.congigs property, only those services you need. You may need no portal services and only the portlet ones, but this is a problem because your portlet services generated by service builder use the portal services.

Using service builder just needs good knowledge of spring and classloading.

But you need to understand the infrastructure before doing that. There are quite a lot of hacks needed... Like

BeanLocator beanLocator = new BeanLocatorImpl(PortalClassLoaderUtil.getClassLoader(), ac);
PortletBeanLocatorUtil.setBeanLocator("portlet", beanLocator);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文