other register

Tuesday, July 03, 2012

Unit Test with Play Framework Sync or Async

The code below illustrate how to do response in sync mode using Play Framework.

object Deals extends Controller {
  def read(id: Long) = Action {
      Ok(readFile(new File("public/files/api/deals/"))).as("application/json").withHeaders(
      "Access-Control-Allow-Origin" -> "*",
      "Content-Type" -> "application/,application/json; charset=utf-8")
Unit test the controller action using scala specs2:

import org.specs2.mutable.Specification
class DealsMockSpec extends Specification {

  def jsonString = "{\"name\": \"jet\"}"
  val jsonPayload: JsValue = Json.parse(jsonString)
  "read action" in {
    val url =
    val result =, url))

    status(result) must equalTo(OK)
    header("Access-Control-Allow-Origin", result) must beSome("*")
    header("Content-Type", result).head must contain("-v")
Using Play Framework to do async programming is really simple. Let's modify the above controller/action code with async features:

Object MyController extends Controller {

  def read(id: Long) = Action {
    val promiseOfString : Promise[String] = Akka.future { readFile(new File("public/files/api/deals/")) }
    Async { => Ok(content).as("application/json").withHeaders(
    "Access-Control-Allow-Origin" -> "*",
    "Content-Type" -> "application/,application/json; charset=utf-8"))

Async code complains about "RuntimeException: There is no started application" when running the above unit test code. 
We have to tell Play! to using a TestServer so that it can handle Promise[ws.Response] which the WS.url("http://localhost:3333/deals/deal/3" will return.

"read action" in {
    running(TestServer(3333)) {
      val result : ws.Response = (WS.url("http://localhost:3333/api/deals/deal/3")).get.await(500).get
      result.status must equalTo(OK)
      result.header("Content-Type").head must contain ("-v")
      result.header("Access-Control-Allow-Origin").head must contain ("*")

Now run:

$play test 

It will pass. And because it is unit test, the speed is much faster than the functional test which requires the application server fully running. 

Monday, July 02, 2012

What a mock application can do for you?

Recently I developed a mock web application based on a RESTful web service specification.

A mock web application can serve as a black box which responses based on the request (i.e. URI and HTTP method). It is easy to set up to implement the API specification.

Request method: GET
Request URI: /api/person/3

Response status code: 200
Response message:  {"name": "jianfeng"} // JSON

In an agile team, the backend dev can be the blocker in different development stages and the mock application can remove the blocker and let different development process (i.e front end, functional test, performance test) go in parallel with backend development..

Blocker 1 - for front end dev

If an agile team is composed of backend and frontend dev, and the front end dev consumes the apis developed by the backend dev. And then here is the blocker and waiting game for the frontend dev, as the backend api is in developing and can be buggy when released.

In this scenario, a mock application can help the frontend dev to continue with their development by calling the mock application instead of the real api. And when the backend dev finishes the api, then the frontend can switch the calling to it.

Blocker 2 - for functional testers

In an agile team, the functional testers can develop their automated script based on the API specification. But their script can only be verified when the backend dev finish their API development. And the testers might rework on their script by then.

The functional testers can verify their automated script by running it against the mock application, make the switch to the real API when the backend dev finish it.

Blocker 3 - for performance testers

In an agile team the performance tester normally get involved at the later stage - when the backend dev finish their API and the functional testers have tested it.

In this scenario, a mock application can let the performance testers start at an early stage. They don't have to wait for the backend dev to finish their API. Instead they can simply make their performance test calls to the mock application.

Wednesday, June 20, 2012

Validate json files in sub directories

import scala.util.parsing.json.JSON

object JsonValidator {
  def main(args: Array[String]) {

    for (file <- recursiveListFiles(new File(".")).filter(_.getName.endsWith(".json"))) {
      val json = JSON.parseFull(fromFile(file).getLines mkString)
      if (json.isEmpty)  // if json file is not valid json
        println(file + ": " + json)

  def recursiveListFiles(f: File): Array[File] = {
    val these = f.listFiles
    these ++ these.filter(_.isDirectory).flatMap(recursiveListFiles)