2013-05-03 14 views
10

Mam WebSocket w mojej aplikacji Play i chcę napisać test na to, ale nie mogłem znaleźć żadnego przykładu, jak napisać taki test. Znalazłem dyskusję w grupie Google play-framework, ale ostatnio nie było żadnej aktywności.Testuj WebSocket w PlayFramework

Czy są jakieś pomysły na testowanie WebSocket w teście Java?

Odpowiedz

3

można pobrać bazowego Iteratee, Enumerator i przetestować je bezpośrednio . W ten sposób nie musisz korzystać z przeglądarki. Potrzebujesz akka-testkit, aby poradzić sobie z asynchroniczną naturą iteratees.

Scala przykład:

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

Załóżmy, że masz biblioteki websocket zwracającą przyszłości [Itearatee [JsValue, jednostkowa] Enumerator [JsValue]] wykorzystuje kontroler

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

I chcesz przetestować tę bibliotekę.

Oto kontekst można użyć:

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)) 
    } 

} 

Zmodyfikowane testy mogą być zapisywane jako

"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")) 
} 

Incoming reprezentują wiadomości pochodzących od strony klienta, a ustępujący reprezentuje wiadomości wysłanych z serwera. Aby napisać test, najpierw wysyłasz przychodzące wiadomości przychodzące, a następnie zamykasz połączenie, wywołując plik incoming.end, a następnie otrzymujesz pełną listę wychodzących wiadomości z metody outgoing.get.

1

Chrome zapewnia testowanie usługi websocket w wersji plugin.

Edit

Więc za pomocą wtyczki (jak pokazano na rysunku poniżej) można zapewnić websocket adres i dane żądania i wysłać wiadomość do serwisu. Dziennik wiadomości pokazuje komunikat wysłany przez klienta, a także odpowiedź usługi.

enter image description here

+1

Chociaż ten link może odpowiedzieć na pytanie, lepiej jest to tutaj zasadnicze części odpowiedzi i podać link do odniesienia. Odpowiedzi dotyczące linków mogą stać się nieprawidłowe, jeśli strona z linkami się zmieni. –

+0

@LawrenceAiello zgadzam się z tobą, moje złe, zakładając, że to było dość trywialne. Zaktualizowałem więcej szczegółów. –