【问题标题】:Test WebSocket in PlayFramework在 PlayFramework 中测试 WebSocket
【发布时间】:2013-05-03 08:15:44
【问题描述】:

我的 Play 应用程序中有一个 WebSocket,我想为它编写一个测试,但我找不到任何关于如何编写这样一个测试的示例。我在play-frameworkGoogle 群里发现了一个讨论,但最近没有任何活动。

那么,对于如何在 Java 测试中测试 WebSocket 有什么想法吗?

【问题讨论】:

    标签: java testing websocket playframework-2.0


    【解决方案1】:

    您可以检索底层的 Iteratee、Enumerator 并直接对其进行测试。这样你就不需要使用浏览器了。不过,您需要 akka-testkit 来应对迭代的异步特性。

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

    【讨论】:

      【解决方案2】:

      我使用 Firefox 测试 WebSockets 代码:

      https://github.com/schleichardt/stackoverflow-answers/commit/13d5876791ef409e092e4a097f54247d851e17dc#L8R14

      对于 Java,将 'HTMLUNIT' 替换为 'FIREFOX' 的效果类似:http://www.playframework.com/documentation/2.1.x/JavaFunctionalTest

      【讨论】:

        【解决方案3】:

        Chrome 提供了一个plugin 来测试 websocket 服务。

        编辑

        所以使用插件(如下图所示),您可以提供 websocket url 和请求数据并将消息发送到服务。消息日志显示从客户端发送的消息以及服务响应。

        【讨论】:

        • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
        • @LawrenceAiello 同意你的观点,我认为这很微不足道。我已经更新了更多细节。
        【解决方案4】:

        假设你有一个 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 代表来自客户端的消息,而 Outcoming 代表来自服务器的消息。要编写测试,您首先输入来自incoming 的传入消息,然后通过调用incoming.end 关闭连接,然后您从outing.get 方法获得传出消息的完整列表。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-12-21
          • 1970-01-01
          相关资源
          最近更新 更多