使用Web套接字在Arquillian TomEE嵌入式测试中进行CDI注入

时间:2015-11-10 12:17:45

标签: websocket cdi spock jboss-arquillian tomee

我正在编写我的@ServerEndpoint的一些集成测试,在最终运行端点之后,我现在在@OnOpen中得到一个nullpointer,因为注入失败了。

我已经在github上传了代码:https://github.com/runarhk/Websockets-Test

端点的定义如下:

@ServerEndpoint("/test")
public class MyEndpoint{

    @Inject
    private SessionHandler sessionHandler;

    @OnOpen
    public void open(Session session) {
        sessionHandler.addSession(session);//sessionhandler is @Singleton
    }

    @OnClose
    public void close(Session session) {
    }

    @OnError
    public void onError(Throwable error) {
    }

    @OnMessage
    public void handleMessage(String payload, Session session) {
    }
}

@Singleton
public class SessionHandler {
    public void addSession(Session session){}

}

@ClientEndpoint
public class SocketClient {

    @OnOpen
    public void onOpen(Session session) {
    }

    @OnMessage
    public void onMessage(String message, Session session) {
    }

    @OnClose
    public void onClose(Session session, CloseReason closeReason) {
        LOGGER.info(String.format("Session %s close because of %s",     session.getId(), closeReason));
    }

    public SocketClient openConnection(URL url) {//URL injected arquillian resource, where url is for http connection..
        WebSocketContainer container = ContainerProvider.getWebSocketContainer();
        try {
            SocketClient  client = new SocketClient();
            URI uri = URI.create(url.toString().replace("http", "ws") + "test");
            container.connectToServer(client, uri);
            return client;
        } catch (DeploymentException | IOException ex) {
            LOGGER.log(Level.SEVERE, null, ex);
            throw new RuntimeException(ex);
        }
    }

    public void closeConnection() {
        try {
            session.close(new CloseReason(CloseReason.CloseCodes.NORMAL_CLOSURE, "Client requested close"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

我的测试是用spock编写的,在设置中失败

@RunWith(ArquillianSputnik)
class SocketIT extends Specification {

    @Deployment
    public static Archive archive() {
       return ShrinkWrap.create(WebArchive.class, "test-sockets.war")
           .addAsWebInfResource(EmptyAsset.INSTANCE, ArchivePaths.create("beans.xml"))
           .addClasses(MyEndpoint.class, SessionHandler.class);
    }
    @ArquillianResource
    URL url;

    SocketClient client;

    def setup() {
        client = SocketClient.openConnection(url);
    }

    def cleanup() {
        client.closeConnection();
    }

    def 'test connection'() {
        given: 'payload'
            def payload = "abc"
        when: 'sending payload'
            client.sendMessage(payload)
        then: 'it should not fail'
            ass
    }
}

我的pom:

<project xmlns="http://maven.apache.org/POM/4.0.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>slimy</groupId>
    <artifactId>test</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>war</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <tomee.version>1.7.2</tomee.version>
        <tomcat.version>7.0.65</tomcat.version>
    </properties>
    <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.5</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.12.4</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>2.18</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.codehaus.gmavenplus</groupId>
                <artifactId>gmavenplus-plugin</artifactId>
                <version>1.4</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>testCompile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.jboss.arquillian</groupId>
                <artifactId>arquillian-bom</artifactId>
                <version>1.1.5.Final</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <!-- TEST DEPENDENCIES  -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.arquillian.spock</groupId>
            <artifactId>arquillian-spock-container</artifactId>
            <version>1.0.0.Beta3</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.spockframework</groupId>
            <artifactId>spock-core</artifactId>
            <version>0.7-groovy-2.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>2.1.8</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat7-websocket</artifactId>
            <version>${tomcat.version}</version>
            <scope>test</scope>
        </dependency>
        <!-- For Arquillian Integration tests in TOMEE -->
        <dependency>
            <groupId>org.apache.openejb</groupId>
            <artifactId>arquillian-tomee-embedded</artifactId>
            <version>${tomee.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.openejb</groupId>
            <artifactId>tomee-embedded</artifactId>
            <version>${tomee.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>javax.websocket</groupId>
            <artifactId>javax.websocket-api</artifactId>
            <version>1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>6.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>

我的Arquillian.xml文件如下所示:

<?xml version="1.0"?>
<arquillian xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://jboss.org/schema/arquillian"
        xsi:schemaLocation="http://jboss.org/schema/arquillian http://www.jboss.org/schema/arquillian/arquillian_1_0.xsd">
    <container qualifier="tomee" default="true">
        <configuration>
            <property name="httpPort">-1</property>
            <property name="stopPort">-1</property>
        </configuration>
    </container>
</arquillian>

编辑: 我刚下载到1.7.2-plus并在那里运行我的应用程序。它就像一个魅力。那么这可能与tomee-embedded不是一个加号变体有关?

编辑:运行测试时的日志:

INFO: OpenWebBeans Container is starting...
nov 12, 2015 7:06:28 PM org.apache.webbeans.plugins.PluginLoader startUp
INFO: Adding OpenWebBeansPlugin : [CdiPlugin]
nov 12, 2015 7:06:28 PM org.apache.webbeans.plugins.PluginLoader startUp
INFO: Adding OpenWebBeansPlugin : [OpenWebBeansJsfPlugin]
nov 12, 2015 7:06:28 PM org.apache.webbeans.config.BeansDeployer validateInjectionPoints
INFO: All injection points were validated successfully.
nov 12, 2015 7:06:28 PM org.apache.openejb.cdi.OpenEJBLifecycle startApplication
INFO: OpenWebBeans Container has started, it took 255 ms.
nov 12, 2015 7:06:28 PM org.apache.openejb.assembler.classic.Assembler startEjbs
INFO: Created Ejb(deployment-id=SessionHandler, ejb-name=SessionHandler, container=Default Singleton Container)
nov 12, 2015 7:06:28 PM org.apache.openejb.assembler.classic.Assembler startEjbs
INFO: Started Ejb(deployment-id=SessionHandler, ejb-name=SessionHandler, container=Default Singleton Container)
nov 12, 2015 7:06:28 PM org.apache.openejb.assembler.classic.Assembler createApplication
INFO: Deployed Application(path=C:\Users\RunarKristiansen\AppData\Local\Temp\arquillian-tomee-app-working-dir\0\test-sockets)
nov 12, 2015 7:06:29 PM socket.MyEndpoint onError
SEVERE: null
java.lang.NullPointerException
    at socket.MyEndpoint.open(MyEndpoint.java:24)
    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:497)
    at org.apache.tomcat.websocket.pojo.PojoEndpointBase.doOnOpen(PojoEndpointBase.java:66)
    at org.apache.tomcat.websocket.pojo.PojoEndpointServer.onOpen(PojoEndpointServer.java:70)
    at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.init(WsHttpUpgradeHandler.java:138)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:651)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

nov 12, 2015 7:06:29 PM org.apache.tomcat.websocket.pojo.PojoEndpointBase onClose
SEVERE: Failed to call onClose method of POJO end point for POJO of type [socket.MyEndpoint]
java.lang.reflect.InvocationTargetException
    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:497)
    at org.apache.tomcat.websocket.pojo.PojoEndpointBase.onClose(PojoEndpointBase.java:107)
    at org.apache.tomcat.websocket.WsSession.fireEndpointOnClose(WsSession.java:501)
    at org.apache.tomcat.websocket.WsSession.doClose(WsSession.java:456)
    at org.apache.tomcat.websocket.WsSession.close(WsSession.java:422)
    at org.apache.tomcat.websocket.WsSession.close(WsSession.java:416)
    at org.apache.tomcat.websocket.pojo.PojoEndpointBase.handleOnOpenError(PojoEndpointBase.java:96)
    at org.apache.tomcat.websocket.pojo.PojoEndpointBase.doOnOpen(PojoEndpointBase.java:79)
    at org.apache.tomcat.websocket.pojo.PojoEndpointServer.onOpen(PojoEndpointServer.java:70)
    at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.init(WsHttpUpgradeHandler.java:138)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:651)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
    at socket.MyEndpoint.close(MyEndpoint.java:29)
    ... 19 more

nov 12, 2015 7:06:29 PM utils.SocketClient onClose
INFO: Session 0 close because of CloseReason: code [1000], reason [null]

java.lang.IllegalStateException: The WebSocket session [0] has been closed and no method (apart from close()) may be called on a closed session
    at org.apache.tomcat.websocket.WsSession.checkState(WsSession.java:710)
    at org.apache.tomcat.websocket.WsSession.getBasicRemote(WsSession.java:409)
    at utils.SocketClient.sendMessage(SocketClient.java:64)
    at socket.SocketIT.test connection(SocketIT.groovy:42)

nov 12, 2015 7:06:29 PM org.apache.openejb.assembler.classic.Assembler destroyApplication
INFO: Undeploying app: C:\Users\RunarKristiansen\AppData\Local\Temp\arquillian-tomee-app-working-dir\0\test-sockets
nov 12, 2015 7:06:30 PM org.apache.coyote.AbstractProtocol stop
INFO: Stopping ProtocolHandler ["http-bio-20001"]
nov 12, 2015 7:06:30 PM org.apache.coyote.AbstractProtocol pause
INFO: Pausing ProtocolHandler ["http-bio-20001"]
nov 12, 2015 7:06:30 PM org.apache.catalina.core.StandardService stopInternal
INFO: Stopping service Tomcat
nov 12, 2015 7:06:30 PM org.apache.coyote.AbstractProtocol destroy
INFO: Destroying ProtocolHandler ["http-bio-20001"]`

0 个答案:

没有答案