Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing a unit test for Play websockets

I am working on a Scala + Play application utilizing websockets. I have a simple web socket defined as such:

def indexWS =  WebSocket.using[String] { request =>

val out = Enumerator("Hello!")
val in = Iteratee.foreach[String](println).map { _ =>
  println("Disconnected")
}


(in,out)
}

I have verified this works using Chrome's console. The issue I'm having is trying to write a unit test for this. Currently I have this:

"send awk for websocket connection" in {
  running(FakeApplication()){
    val js = route(FakeRequest(GET,"/WS")).get

    status(js) must equalTo (OK)
    contentType(js) must beSome.which(_ == "text/javascript")
  }
}

However, when running my tests in play console, I receive this error, where line 35 corresponds to this line 'val js = route(FakeRequest(GET,"/WS")).get':

NoSuchElementException: None.get (ApplicationSpec.scala:35)

I have not been able to find a good example of unit testing scala/play websockets and am confused on how to properly write this test.

like image 737
vikash dat Avatar asked Oct 10 '13 21:10

vikash dat


People also ask

Why does WebSockets need to be tested?

In order to maintain the confidentiality and integrity of information during the entire process, it is essential to verify that the WebSocket connection uses SSL to transport sensitive wss:// information. It is also essential to check the SSL implementation for security issues.


1 Answers

Inspired by answer from bruce-lowe, here is the alternative example with Hookup:

import java.net.URI
import io.backchat.hookup._
import org.specs2.mutable._
import play.api.test._
import scala.collection.mutable.ListBuffer

class ApplicationSpec extends Specification {

  "Application" should {

    "Test websocket" in new WithServer(port = 9000) {
      val hookupClient = new DefaultHookupClient(HookupClientConfig(URI.create("ws://localhost:9000/ws"))) {
        val messages = ListBuffer[String]()

        def receive = {
          case Connected =>
            println("Connected")

          case Disconnected(_) =>
            println("Disconnected")

          case JsonMessage(json) =>
            println("Json message = " + json)

          case TextMessage(text) =>
            messages += text
            println("Text message = " + text)
        }

        connect() onSuccess {
          case Success => send("Hello Server")
        }
      }

      hookupClient.messages.contains("Hello Client") must beTrue.eventually
    }

  }

}

The example assumed the websocket actor would reply with "Hello Client" text.

To include the library, add this line to libraryDependencies in build.sbt:

"io.backchat.hookup" %% "hookup" % "0.4.2"

like image 143
jordom Avatar answered Oct 18 '22 02:10

jordom