2013-05-03 6 views
10

J'ai une WebSocket dans mon application Play et je veux écrire un test pour celle-ci, mais je n'ai trouvé aucun exemple sur la façon d'écrire un tel test. J'ai trouvé une discussion dans le groupe Google play-framework mais aucune activité n'a eu lieu récemment.Test WebSocket dans PlayFramework

Alors, y a-t-il des idées sur la façon de tester WebSocket dans un test Java?

Répondre

3

Vous pouvez récupérer sous-jacente Iteratee, recenseur et de les tester directement . De cette façon, vous n'avez pas besoin d'utiliser un navigateur. Vous avez besoin d'akka-testkit, pour faire face à la nature asynchrone d'iteratees.

Un exemple Scala:

object WebSocket extends Controller { 
    def websocket = WebSocket.async[JsValue] { request => 
    Future.successful(Iteratee.ignore[JsValue] -> Enumerator.apply[JsValue](Json.obj("type" -> "error"))) 
    } 
} 

class WebSocketSpec extends PlaySpecification {  
    "WebSocket" should { 
    "respond with error packet" in new WithApplication { 
     val request = FakeRequest() 

     var message: JsValue = null 
     val iteratee = Iteratee.foreach[JsValue](chunk => message = chunk)(Akka.system.dispatcher) 

     Controller.websocket().f(request)(Enumerator.empty[JsValue],iteratee) 

     TestKit.awaitCond(message == Json.obj("type" -> "error"), 1 second) 
    } 
    } 
} 
0

Supposons que vous avez une bibliothèque de websocket qui retourne l'avenir [Itearatee [JsValue, Unité], recenseur [JsValue]] votre contrôleur utilise

trait WSLib { 
    def connect: Future[Itearatee[JsValue, Unit], Enumerator[JsValue]] 
} 

Et vous voulez tester cette bibliothèque.

Voici un contexte que vous pouvez utiliser:

trait WebSocketContext extends WithApplication { 
    val aSecond = FiniteDuration(1, TimeUnit.SECONDS) 


    case class Incoming(iteratee: Iteratee[JsValue, Unit]) { 

    def feed(message: JsValue) = { 
     iteratee.feed(Input.El(message)) 
    } 

    def end(wait: Long = 100) = { 
     Thread.sleep(wait) //wait until all previous fed messages are handled 
     iteratee.feed(Input.EOF) 
    } 
    } 

    case class OutGoing(enum: Enumerator[JsValue]) { 
    val messages = enum(Iteratee.fold(List[JsValue]()) { 
     (l, jsValue) => jsValue :: l 
    }).flatMap(_.run) 

    def get: List[JsValue] = { 
     Await.result(messages, aSecond) 
    } 
    } 

    def wrapConnection(connection: => Future[Iteratee[JsValue, Unit], Enumerator[JsValue]]): (Incoming, OutGoing) = { 
    val (iteratee, enumerator) = Await.result(conn, aSecond) 
    (Incoming(iteratee), OutGoing(enumerator)) 
    } 

} 

Ensuite, vos tests peuvent être écrits comme

"return all subscribers when asked for info" in new WebSocketContext { 
    val (incoming, outgoing) = wrapConnection(myWSLib.connect) 

    incoming.feed(JsObject("message" => "hello")) 
    incoming.end() //this closes the connection 


    val responseMessages = outgoing.get //you only call this "get" after the connection is closed 
    responseMessages.size must equalTo(1) 
    responseMessages must contain(JsObject("reply" => "Hey")) 
} 

entrants représentent les messages provenant du côté client, tandis que le sortant représente les messages envoyés du serveur. Pour écrire un test, vous devez d'abord introduire les messages entrants dans les messages entrants, puis fermer la connexion en appelant incoming.end, puis vous obtenez la liste complète des messages sortants de la méthode outgoing.get.

1

Chrome fournit un plugin pour tester le service Websocket.

Modifier

Donc, en utilisant le plugin (comme le montre l'image ci-dessous), vous pouvez fournir url websocket et les données de demande et d'envoyer un message au service. Et le journal des messages montre le message envoyé par le client et aussi la réponse du service.

enter image description here

+1

Bien que ce lien peut répondre à la question, il est préférable d'inclure les éléments essentiels de la réponse ici et de fournir le lien de référence. Les réponses à lien uniquement peuvent devenir invalides si la page liée change. –

+0

@LawrenceAiello d'accord avec vous, mon mal à supposer que c'était assez trivial. J'ai mis à jour plus de détails. –