Testing

Pick a route, say Main.mainRoutes.

Develop a test for the route using specs2 or ScalaTest. Depending on the testing framework you should be using different traits as described in spray-testkit.

In the following example I've used Specs2RouteTest:

package pl.japila.dictionary

import org.specs2._
import spray.http.MediaTypes
import spray.routing.HttpService
import spray.testkit.Specs2RouteTest

class MainTest extends mutable.Specification with Specs2RouteTest with HttpService with RuleComponent {
  def actorRefFactory = system

  "The uservice" should {
    "return a list of available rules for GET requests to the root path" in {
      Get() ~> Main.mainRoutes ~> check {
        mediaType === MediaTypes.`application/json`

        import RuleJsonProtocol._
        import spray.httpx.SprayJsonSupport._
        import spray.httpx.unmarshalling._
        val Right(rules) = response.entity.as[Seq[Rule]]

        rules.size === 3
        rules.contains(Rule(Some(0)))
        rules.contains(Rule(Some(1)))
        rules.contains(Rule(Some(10), node = "10", app = "APP", obj = "OBJ", mgr = "MGR"))
      }
    }
  }
}

For the JSON to work, you have to write your own custom unmarshaller as follows:

object RuleJsonProtocol extends DefaultJsonProtocol {

  implicit object RuleFormat extends RootJsonFormat[Rule] {
    def write(r: Rule) = {
      val fields = Map(
        "id" -> JsNumber(r.id.get),
        "node" -> JsString(r.node),
        "app" -> JsString(r.app),
        "obj" -> JsString(r.obj),
        "mgr" -> JsString(r.mgr)
      ) ++ r.kvs.map { case (k, v) => k -> JsString(v)}
      JsObject(fields)
    }

    def read(value: JsValue) = {
      val fs = value.asJsObject.fields
      val id = fs.get("id").map(_.convertTo[Long])
      val node = fs("node").convertTo[String]
      val app = fs("app").convertTo[String]
      val obj = fs("obj").convertTo[String]
      val mgr = fs("mgr").convertTo[String]
      val kvs = fs.filterKeys { key => !Set("id", "node", "app", "obj", "mgr").contains(key)}.map { case (k, v) =>
        k -> v.convertTo[String]
      }
      Rule(id, node, app, obj, mgr, kvs)
    }
  }

}

Once the implicit object RuleFormat is in scope, Spray takes care of the marshalling and unmarshalling.

You may want to read the official documentation about spray-json Support.

results matching ""

    No results matching ""