UserCredentials
. В интеграционном тесте у вас обычно нет HttpRequest или HttpSession для работы (по крайней мере, если вы не выполняете тесты, включающие ваш пользовательский интерфейс). Поэтому вам нужна инфраструктура для тестирования интеграции. С обеими технологиями это немного озадачивает, чтобы эта инфраструктура заработала. Получите свою собственную картину этого.
Если вы новичок в области видимости и контексте в CDI и Spring, ознакомьтесь с основами и получите обзор различных областей применения.
Интеграционное тестирование объединенных бобов в Spring
В Spring 3.1 отсутствует поддержка интеграционных тестов для сессионных компонентов или компонентов запроса (см. Здесь ). Это запланировано на весну версии 3.2. Тем не менее, эта ссылка объясняет решение, которое работало для меня.
Сначала вам нужно разработать SessionScope для теста. Его целью является макет HttpRequest и HttpSession.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
package com.mycompany.springapp.scope; import org.springframework.beans.factory.InitializingBean; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpSession; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.request.SessionScope; public class SetupSession extends SessionScope implements InitializingBean { public void afterPropertiesSet() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpSession session = new MockHttpSession(); request.setSession(session); RequestContextHolder.setRequestAttributes( new ServletRequestAttributes( request)); } } |
Чтобы зарегистрировать этот класс в качестве объекта управления областью сеанса в вашем test-beans.xml
сделайте следующее:
01
02
03
04
05
06
07
08
09
10
11
12
|
|
Обратите внимание, что я зарегистрировал области действия после context:component-scan
тэг context:component-scan
,
Наконец, я написал свой тестовый класс:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.util.Assert; @ContextConfiguration ( "/test-beans.xml" ) @RunWith (SpringJUnit4ClassRunner. class ) public class MyScopeBeanTest { @Autowired private MyScopeBean myScopeBean; @Test public void testBeanScopes() { Assert.isTrue(myScopeBean.getMyCustomScopedService().getName().equals( "Test" )); Assert.isTrue(myScopeBean.getMySessionScopedService().getName().equals( "Test" )); } } |
Обратите внимание, что я вызвал метод getName()
EJB. Это необходимо для обеспечения работоспособности. Клиентский прокси-сервер может быть внедрен в точку внедрения, но если вы сделаете вызов прокси-серверу, у него не будет ссылки на объект области действия и сотрудничающий объект соответственно.
Интеграционное тестирование объединенных бобов с CDI
Инструмент, который я использовал для тестирования интеграции CDI — Arquillian . Есть альтернативы. Вы можете использовать Weld «изначально», если тестируете только с классами CDI. Но если у вас также есть EJB, этого недостаточно. Arquillian поставляется с разумным количеством переходных зависимостей. Давайте посмотрим, как все будет работать.
Примечание: без Maven вы потерялись здесь в пустыне, поэтому я призываю вас использовать его! Я попробовал m2eclipse для Helios, у меня это не сработало, я вернулся к старой доброй командной строке, используя Maven 3.
pom.xml
В этих примерах предполагается, что у вас работает проект Java EE, вы также можете посмотреть здесь, как настроить новый проект Java EE 6. Для интеграции Arquillian внесите следующие изменения в ваш файл pom.xml
:
В разделе свойств:
1
|
1.0.0.Alpha5 |
Добавьте этот репозиторий:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
repository.jboss.org default true never warn false always warn |
Это официальный репозиторий JBoss Maven, в котором доступны все дистрибутивы Arquillian.
Добавьте следующие зависимости в ваш pom.xml
:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
junit junit 4.8.1 test org.jboss.arquillian arquillian-junit ${arquillian.version} test org.jboss.arquillian.container arquillian-glassfish-remote-3.1 ${arquillian.version} test javax.enterprise cdi-api 1.0-SP4 test |
Первая зависимость — это ваша среда JUnit для написания интеграционных тестов. Вторая зависимость объединяет Arquillian с JUnit. Третья зависимость объединяет ваш контейнер развертывания. Для меня это моя установка Glassfish. Последняя зависимость — это API-интерфейс CDI, который должен быть доступен для ваших тестов CDI.
Обратите внимание, что в строке 17 я использую установку Glassfish 3.1 в качестве контейнера развертывания, а Arquillian использует удаленные вызовы для выполнения тестов. Вам необходимо настроить собственную среду развертывания здесь. См. JBoss Maven Repo для правильного значения artifactId
. С Arquillian вашей целевой средой также может быть встроенный контейнер, такой как JBoss Embedded AS, GlassFish Embedded или Weld SE. В этом случае вам не нужна отдельная установка контейнера и удаленные вызовы, все работает локально («в памяти»).
Вы делаете mvn eclipse: eclipse после добавления зависимостей для вашей целевой среды.
Наконец я написал свой первый класс тестирования интеграции Arquillian:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
import javax.inject.Inject; import junit.framework.Assert; import org.jboss.arquillian.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ArchivePaths; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.junit.Test; import org.junit.runner.RunWith; import com.mycompany.jeeapp.scope.MyApplicationService; import com.mycompany.jeeapp.scope.MyConversationService; import com.mycompany.jeeapp.scope.MyDefaultService; import com.mycompany.jeeapp.scope.MyRequestService; import com.mycompany.jeeapp.scope.MyScopeBean; import com.mycompany.jeeapp.scope.MySessionService; import com.mycompany.jeeapp.scope.MySingletonService; import com.mycompany.jeeapp.scope.extension.MyCustomScopeService; @RunWith (Arquillian. class ) public class MyArquillianJUnitTest { @Inject private MyScopeBean myScopeBean; @Deployment public static JavaArchive createTestArchive() { return ShrinkWrap .create(JavaArchive. class , "test.jar" ) .addClasses(MyScopeBean. class ,MyApplicationService. class , MyConversationService. class , MyDefaultService. class , MyRequestService. class , MySessionService. class , MySingletonService. class , MyCustomScopeService. class ) .addAsManifestResource(EmptyAsset.INSTANCE, ArchivePaths.create( "beans.xml" )); } @Test public void testScopedBeans() { Assert.assertTrue(myScopeBean.getApplicationService().getSomeName() .equals( "myName" )); Assert.assertTrue(myScopeBean.getApplicationServiceWithNew().getSomeName() .equals( "myName" )); Assert.assertTrue(myScopeBean.getCustomScopeService().getSomeName() .equals( "myName" )); Assert.assertTrue(myScopeBean.getDefaultService().getSomeName() .equals( "myName" )); Assert.assertTrue(myScopeBean.getRequestService().getSomeName() .equals( "myName" )); Assert.assertTrue(myScopeBean.getSessionService().getSomeName() .equals( "myName" )); Assert.assertTrue(myScopeBean.getSingletonService().getSomeName() .equals( "myName" )); } } |
Вывод
В настоящий момент Spring не предлагает интегрированной поддержки тестирования для bean-компонентов с областью видимости. Это было очень удивительно, так как Spring всегда придавал большое значение всем темам тестирования. Существует обходной путь, который я описал в своем блоге. Это было не сложно сделать эту работу. Полная поддержка тестирования интеграции запланирована на Выпуск 3.2 M1.
Тестирование bean-объектов CDI включено с помощью Arquillian. У меня были некоторые проблемы во время установки (см. Последний абзац ниже), которые, как мне кажется, обычны, если вы используете новую технологию. Тот факт, что вы должны передать все тестируемые компоненты в архив (см. Метод @Deployment
) — это то, что мне нужно попробовать в большом проекте: это действительно хорошая идея? Иногда большие приложения соединяются вместе с десятками бинов из разных пакетов. Трудно предсказать, какие компоненты используются в интеграционном тесте.
Проблемы и решения
Некоторые настройки Arquillian имеют так много зависимостей, что вы не можете использовать стандартные конфигурации запуска Eclipse. Сгенерированный аргумент командной строки превышает ограничение длины Windows для команд командной строки. Поэтому я использовал Ant-Script для запуска теста. Сценарий только для иллюстрации. Вы должны создать свой собственный скрипт Ant. Вы можете получить информацию о вашем classpath следующим образом: в Eclipse перейдите к «File> Export> General> Ant buildfiles», чтобы сгенерировать информацию о вашем classpath. Возьмите эту информацию о пути к классам и поместите ее в скрипт запуска теста Ant JUnit. Я задокументировал мой полный скрипт Ant здесь .
Когда я запустил этот Ant-скрипт, у меня все работало нормально. Если у вас есть какие-либо проблемы, дайте мне знать, вы можете просмотреть файл результатов теста и файл server.log
для анализа.
WELD-001303 Нет активных контекстов для типа области javax.enterprise.context.ConversationScoped
-> ConversationScope связан с JSF спецификацией EE. Таким образом, они не будут активны во время обычного HTTP-запроса, что и делает Аркиллиан.
POST http: // localhost: 4848 / management / domain / apps / application возвратил статус ответа 403
-> 404/403 ошибки могут быть проблемами развертывания, проверьте server.log для основной причины (моя была в том, что у меня не было всех необходимых классов, добавленных в test.jar
)
Возникла исключительная ситуация при выполнении командной строки.
Не удалось запустить программу «D: \ dev_home \ java-6-26 \ bin \ javaw.exe» (в каталоге «D: \ dev_home \ repositories \ git \ jee-app-weld \ jee-app-weld»): ошибка CreateProcess = 87, параметр Фальшера
-> Classpath превышает допустимую длину для операций командной строки Windows. Вам нужно использовать скрипт Ant или Maven для запуска тестов.
ValidationException: DeploymentScenario содержит цели, не обрабатывающие какой-либо определенный контейнер в реестре.
-> смотрите здесь .
WELD-000072 Управляемый компонент, объявляющий пассивирующую область, должен поддерживать пассивацию. Бин: управляемый бин [класс com.mycompany.jeeapp.scope.example.UserCredentials] с квалификаторами [@Any @Default]
-> Вам нужно реализовать Serializable на бинах Session- и Conversation-Scoped.
DeploymentScenario содержит цели, не обрабатывающие какой-либо определенный контейнер в реестре. _ДЕФОЛТ_
-> смотрите здесь .
java.net.ConnectException: соединение отказано: подключиться
-> Ваш удаленный сервер Java EE не запущен, запустите его!
Ссылка: «Интеграционное тестирование bean-объектов scoped в CDI 1.0 и Spring 3.1» от нашего партнера JCG Никласа.