Модульное тестирование в Liferay

Кто-нибудь знает, как запускать юнит-тесты для портлетов Liferay? Я нашел много сообщений об этом (например, http://agile-reflections.opnworks.com/2010/06/portlet-unit-testing-with-liferay-6.html), но, тем не менее, не работает.

3 ответа

Это может быть излишним, но если вы ищете корпоративный подход с непрерывным интеграционным тестированием, этот блог дает очень хороший пример: непрерывная интеграция в Liferay: запуск тестов Selenium 2 в пакете Tomcat 6

Модульное тестирование портлетов Liferay довольно сложно, когда используется ServiceBuilder.

Причина в том, что он генерирует довольно тяжелые сервисы, которые содержат ссылки не только на bean-объекты внутри Portlet, но даже на bean-компоненты Portal, генерируемые ServiceBuilder.

Есть такие инструменты, как 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

Это определения пружин, которые будут загружены для тестирования контекста приложения. Все бы хорошо, но bean-компоненты из portlet-spring.xml - это те тяжелые сервисы, которые содержат ссылки на определения bean-компонентов Portal, такие как ResourceService, UserLocalService, CounterLocalService, и вам придется загружать даже META-INF/portal-spring.xml и поверьте мне, это не так просто, потому что вам придется загружать много других вещей.

ОТВЕТ:

Правда в том, что вам, скорее всего, не понадобится юнит-тестирование служб SB портлета, никогда. Они представляют сущности с постоянством и уровнем обслуживания вокруг. То, что не должно быть проверено. Вы просто должны издеваться над ними и заглушить их методы, верно?

И лучший способ для тестирования юнитов и интеграций в отношении макетов - это не использовать статические классы *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;

Написание модульных / интеграционных тестов для этого портлета было бы довольно просто, верно? Вы просто создаете весенний контекст для тестирования и издеваетесь над этими сервисами:

Использование Service Builder того стоит, но вы должны иметь некоторые знания Spring и поиграть с ним некоторое время. Тогда это сэкономит много времени, потому что его легко обслуживать.

Вам нужно иметь сторонние библиотеки на classpath.

Ключевым моментом является наличие даже portal-impl.jar и других зависимостей портала от пути к классам и наличие InitUtil.initWithSpring(boolean); загрузите основные конфигурации xml Spring, которые вы указали в spring-ext.properties в свойстве spring.congigs, только те сервисы, которые вам нужны. Возможно, вам не нужны никакие сервисы портала, а только портлетные, но это проблема, потому что ваши сервисы портлетов, генерируемые компоновщиком сервисов, используют сервисы портала.

Для использования сервис-компоновщика просто необходимы хорошие знания о весне и загрузке классов.

Но вы должны понимать инфраструктуру, прежде чем делать это. Требуется довольно много хаков...

BeanLocator beanLocator = new BeanLocatorImpl(PortalClassLoaderUtil.getClassLoader(), ac);
PortletBeanLocatorUtil.setBeanLocator("portlet", beanLocator);
Другие вопросы по тегам