2013-05-03 2 views
10

У меня есть приложение WebSocket в приложении Play, и я хочу написать для него тест, но я не мог найти никакого примера, как написать такой тест. Я нашел дискуссию в группе play-framework Google, но в последнее время активности не было.Тест WebSocket в PlayFramework

Итак, есть ли идеи по тестированию WebSocket в тесте Java?

ответ

3

Вы можете получить основной Iteratee, Enumerator и проверить их непосредственно , Таким образом, вам не нужно использовать браузер. Тебе нужен акка-тесткит, чтобы справиться с асинхронным характером итераций.

на 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

Предположим, что у вас есть библиотека WebSocket, возвращающую Future [Itearatee [JsValue, Unit], Enumerator [JsValue]] контроллер использует

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

И вы хотите протестировать эту библиотеку.

Вот контекст вы можете использовать:

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

} 

Тогда ваши тесты могут быть записаны как

"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.end, после чего вы получаете полный список исходящих сообщений из метода outgoing.get.

1

Хром предоставляет plugin для проверки обслуживания websocket.

Редактировать

Таким образом, используя плагин (как показано на рисунке ниже) вы можете предоставить WebSocket URL и данные запроса и отправить сообщение в службу. Журнал сообщений показывает сообщение, отправленное с клиента, а также ответ службы.

enter image description here

+1

Хотя эта ссылка может ответить на этот вопрос, то лучше включить основные части ответа здесь и предоставить ссылку для справки. Ответные ссылки могут стать недействительными, если связанная страница изменится. –

+0

@LawrenceAiello согласен с тобой, мой плохо предположить, что это было довольно тривиально. Я обновил более подробную информацию. –