2016-04-23 11 views
6

Java EE 7で提供されているAPIを使用してWebSocketを実装しました。さらに、問題なくWebSocketを要求するクライアントを実装しました。いくつかのコード変更を実行する際にこれが機能していることを確認するために、ビルドサーバーで実行できるテストを実装したいと考えています。ジェンキンスCIだけでなく、ローカル。私はmavenを使用しています。Java EE7 Websocketのテスト方法

は、ここに私のサーバーのエンドポイントです:

import javax.enterprise.context.ApplicationScoped; 
import javax.websocket.*; 
import javax.websocket.server.ServerEndpoint; 
import java.io.IOException; 
import java.util.Collections; 
import java.util.HashSet; 
import java.util.Set; 

@ApplicationScoped 
@ServerEndpoint("/example") 
public class WebSocket { 

    private final Set<Session> sessions = Collections.synchronizedSet(new HashSet<>()); 

    @OnOpen 
    public void open(Session session) { 
     sessions.add(session); 
    } 

    @OnClose 
    public void close(Session session) { 
     sessions.remove(session); 
    } 

    @OnError 
    public void onError(Throwable error) { 
     //TODO do something 
    } 

    @OnMessage 
    public void handleMessage(String message, Session session) throws IOException { 
     session.getBasicRemote().sendText("Hello "+message+"!"); 
    } 
} 

ここに私のクライアントエンドポイントです:

import javax.websocket.*; 
import java.io.IOException; 
import java.net.URI; 

@ClientEndpoint 
public class WebsocketClient { 

    private String uri = "ws://localhost:8181/<some-path>/example"; 
    private Session userSession = null; 
    private String answer; 

    public WebsocketClient() { 
     try { 
      WebSocketContainer container = ContainerProvider 
       .getWebSocketContainer(); 
      container.connectToServer(this, new URI(uri)); 
     } catch (Exception e) { 
      throw new RuntimeException(e); 
     } 
    } 

    public boolean isClosed() { 
     return userSession == null || !userSession.isOpen(); 
    } 

    @OnOpen 
    public void onOpen(Session userSession) { 
     this.userSession = userSession; 
    } 

    @OnClose 
    public void onClose(Session userSession, CloseReason reason) { 
     this.userSession = null; 
    } 

    @OnMessage 
    public void onMessage(String message) { 
     this.answer = message; 
    } 

    public String getAnswer() { 
     return answer; 
    } 

    public void sendMessage(String message) { 
     if (userSession != null && userSession.isOpen()) 
      try { 
       this.userSession.getBasicRemote().sendText(message); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     else { 
      System.out.println("Session closed!"); 
     } 
    } 

    public void reset() { 
     this.answer = null; 
    } 
} 

私もCDIを使用してビルドサーバー上でテストされているいくつかの他のクラスを持っています。 CDIやその他のアプリケーションコンテナの機能を使用できるようにするために、をApacheのTomeEE/OpenEJBバージョン7.0.0-M3で使用しています。組み込みのTomEEを起動するとテストが実行され、その後シャットダウンします。このアプローチを使用すると、呼び出すURLがありません。これは、たとえばJAX-RS RESTサービスでは、テストでクラスメソッドを呼び出して応答を確認するだけです。しかし、どのようにWebSocketでこれを行うのですか?私はただ単に不足のためにメソッドを呼び出すことはできませんSession

私の現在のテストでは、次のようになります。

import org.apache.openejb.junit.jee.EJBContainerRunner; 
import org.junit.Test; 
import org.junit.runner.RunWith; 

import java.net.SocketException; 

import static org.hamcrest.MatcherAssert.assertThat; 
import static org.hamcrest.Matchers.equalTo; 
import static org.hamcrest.Matchers.is; 

@RunWith(EJBContainerRunner.class) 
public class TestWebsocket { 

    private WebsocketClient socket; 

    @Test 
    public void test() throws SocketException { 
     String answer = requestSynchronous("Java"); 
     assertThat(answer, is(equalTo("Hello Java!"))); 
    } 

    public String requestSynchronous(String message) throws SocketException { 
     if (socket == null || socket.isClosed()) { 
      socket = new WebsocketClient(); 
     } 
     socket.reset(); 
     socket.sendMessage(message); 
     String answer = null; 
     int i = 0; 
     while (answer == null && i < 10000) { 
      try { 
       answer = socket.getAnswer(); 
       Thread.sleep(1); 
       i++; 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
     if (answer != null) 
      return answer; 
     else throw new SocketException("Connection timeout"); 
    } 

} 

これは、例えばと私のローカルマシン上TomEEを実行している作品tomee-maven-plugin。しかし、このアプローチはビルドサーバーでは実行できません。特別なポートを設定するか、テスト用に仮想マシンを設定するより簡単な方法はありますか?

ありがとうございます!

答えて

6

私は、VMを使用して、からかっせずに私のテストの問題の解決策を見つけた...

session.getBasicRemote().sendText("...");を呼び出すために必要なされていないクライアントへの応答メッセージを送信します。代わりに、送信するメッセージを返します。

クラスのhandleMessage方法WebSocketへの変更:

@OnMessage 
public String handleMessage(String message){ 
    return "Hello "+message+"!"; 
} 

そして、テストがに簡素化:Webアプリケーションコンテナの外にメッセージを送信しません

@RunWith(EJBContainerRunner.class) 
public class TestWebsocket { 

    @Inject 
    private WebSocket socket; 

    @Test 
    public void test() throws SocketException { 
     String answer = socket.handleMessage("Java"); 
     assertThat(answer, is(equalTo("Hello Java!"))); 
    } 
} 

このアプローチはその試験のために開始される。これにより、テストをより簡単に処理できます。

関連する問題