Как использовать конечную точку почты Citrus в тесте Arquillian на сервере JEE - PullRequest
1 голос
/ 18 октября 2019

У меня есть веб-приложение на Java, где вызов REST запускает почту, отправленную через javax.mail.Session. Приложение развернуто как архив .war, который я хочу протестировать на сервере JBoss EAP 7.2.

Я использую Arquillian 1.5.0.Final и Citrus Framework версии 2.8.0. Моя система сборки Gradle 5.x, и все использует среду выполнения Java 8.

Я хотел бы создать конечную точку почты Citrus и использовать Arquillian для обеспечения этого внутри контейнера JEE. Мой опыт работы с этими платформами ограничен несколькими днями, поэтому я начинаю с примера приложения, чтобы получить больше знаний:

У меня есть следующее, работающее с простой веб-конечной точкой (HelloServlet от https://guides.gradle.org/building-java-web-applications/):

@RunWith(Arquillian.class)
public class HelloServletTest {
    @CitrusFramework
    private Citrus citrusFramework;

    @ArquillianResource
    private URL baseUri;

    private String serviceUri;

    @Deployment(testable = false)
    public static WebArchive createDeployment() {
        final WebArchive war = ShrinkWrap.create(WebArchive.class)
                .addClass(HelloServlet.class)
                .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
        // [...]
        return war;
    }

    @Before
    public void setUp() throws Exception {
        serviceUri = new URL(baseUri, "hello").toExternalForm();
    }

    @Test
    @CitrusTest
    public void smokeTest(@CitrusResource TestDesigner designer) throws InterruptedException {
        System.err.println("ServiceURI: " + serviceUri);
        designer.send(serviceUri)
                .message(new HttpMessage("?name=Jacob")
                        .method(HttpMethod.POST));
        designer.receive(serviceUri).message(new HttpMessage("").status(HttpStatus.OK));
        citrusFramework.run(designer.getTestCase());

    }
}

Я использую @Deployment(testable=false), так как в этом примере выполняется проверка на стороне клиента. Однако моя конечная цель - использовать Citrus внутри контейнера, поэтому я понимаю, что мне нужно иметь @Deployment(testable=true). Но когдаЯ запускаю тест с testable=true, выбрасывается NPE:

java.lang.NullPointerException
    at com.consol.citrus.annotations.CitrusAnnotations.injectAll(CitrusAnnotations.java:61)
    at com.consol.citrus.arquillian.enricher.CitrusTestEnricher.enrich(CitrusTestEnricher.java:57)
    at org.jboss.arquillian.junit.RulesEnricher.enrichInstances(RulesEnricher.java:85)
    at org.jboss.arquillian.junit.RulesEnricher.enrichStatement(RulesEnricher.java:77)
[...]
    at org.jboss.arquillian.core.impl.EventContextImpl.invokeObservers(EventContextImpl.java:103)
    at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:90)
    at org.jboss.arquillian.container.test.impl.client.ContainerEventController.createContext(ContainerEventController.java:128)
    at org.jboss.arquillian.container.test.impl.client.ContainerEventController.createBeforeContext(ContainerEventController.java:114)
[...]
  at org.jboss.arquillian.test.impl.EventTestRunnerAdaptor.fireCustomLifecycle(EventTestRunnerAdaptor.java:159)
    at org.jboss.arquillian.junit.Arquillian$7.evaluate(Arquillian.java:273)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
[...]
  at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
[...]
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
    at java.lang.Thread.run(Thread.java:748)

Мой arquillian.xml

<?xml version="1.0" encoding="UTF-8"?>
<arquillian xmlns="http://jboss.org/schema/arquillian" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">

    <defaultProtocol type="Servlet 3.0"/>

    <engine>
        <property name="deploymentExportPath">build/deployments</property>
    </engine>

    <container qualifier="wildfly-managed" default="true">
    </container>

    <extension qualifier="citrus">
        <property name="autoPackage">false</property>
        <property name="citrusVersion">2.8.0</property>
    </extension>
</arquillian>

Мой citrus-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:citrus-mail="http://www.citrusframework.org/schema/mail/config"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
              http://www.citrusframework.org/schema/mail/config http://www.citrusframework.org/schema/mail/config/citrus-mail-config.xsd">

    <!-- Mail server mock -->
    <citrus-mail:server id="mailServer"
                        auto-start="true"
                        port="2222"/>
</beans>

Мои вопросы:

  • Имеет ли смысл мой подход? Возможно ли использовать Citrus и Arquillian таким образом?
  • Ожидается ли исключение NPE или я пропускаюкакая-то зависимость или конфигурация?
...