snippetをspecする

Lift snippetでリクエストパラメータを扱うときのテストケースの作り方。ここではSpecsとMockitoを使って、Servletコンテキストをエミュレートします。

一次情報

[Liftweb wiki]How To: Unit test lift snippets with a logged in user
[Liftweb ML]
[specs wiki]Execute the Example expectations inside a specific context

環境準備

specs1.6.1以上と、モック生成ライブラリMockitoを使ったやり方です。特にspecs1.6.0では動かないのでバージョンに注意。

simple-build-toolの場合の設定方法:

  class MyProject(info: ProjectInfo) extends DefaultWebProject(info){
      :
    val specs = "org.scala-tools.testing" % "specs" % "1.6.1" % "test"
    val mockito = "org.mockito" % "mockito-core" % "1.8.1" % "test"
      :
  }


S.paramをテストするサンプル

例:リクエストパラメータに応じたコンテンツを取得してリンクを生成するSnippet

class ProductLinkTo {

  def edit( xhtml:NodeSeq ) = S.param("product_id") match {
    case Full(id) =>
     Product.find(id.toLong) match {
      case Full( p ) => <a href={"/product/edit/"+p.id}>{p.title}を編集</a>
      case _ => <span>Not Found</span>
    }
    case _ => <span>Access Error</span>
  }
}

ここで問題になるのは、Webコンテナを動かさないと「S」オブジェクトの操作ができないわけですが、HttpRequestのモックを使ってエミュレートします。
このSnippetのspecsは以下になります。


object ProductLinkToSpec extends Specification with Mockito {

  var request = mock[Req] //requestのモックを生成
  var session = new LiftSession("", StringHelpers.randomString(20), Empty)

  //request/sessionのコンテキスト内でスペックfを実行する。
  def inSession(f: =>Any) {
    S.init(request, session) { f }
  }

  //モックRequestへのパラメーターセッター
  def setParameter(name: String, value: String){
    request.param(name) returns Some(value)
  }

  new SpecContext{
    beforeSpec{ (new bootstrap.liftweb.Boot).boot }
    //各スペックをinSession内で実行する。
    aroundExpectations(inSession(_))
  }

  "LinkTo Snippet" should {

  "build link" in {

    //Productを生成してidをリクエストパラメータへ
    var product_id = Product.create.title("商品").saveMe.id.is
    setParameter("product_id",product_id.toString)

    //snippetはちゃんとリンクを返しているか。
    //specs.XMLMatcherなどを参考に
    val snippet = new ProductLinkTo
    snippet.edit(NodeSeq.Empty) must \\("a")

    Product.find(product_id).open_!.delete_!
  }
  }
}


snippetの入出力はXML型なのでScalaでは扱いやすい(テスト書きやすい)。例えば「生成したリストが何行か」といったテストは一発で書けるでしょう。

 snippet.list( node ) \\ "li" length must be 15

とか。specsでもXMLMatcherは標準添付。

LiftのコアアーキテクチャであるSnippetが非常にさくさくテスト駆動開発できる点には結構注目してよいと思う。ここまでViewテストがしやすいフレームワーク&言語は他にナイんじゃないかなと思います。


※パラメータだけでなく、SessionやHTTPレスポンスのテスト方法なども気がついたことあったら書き足していくこと>オレ


同じカテゴリのエントリ
1.Lift再入門 / 8.javascriptからsubmitできない / 7.Ajax Form / 6.Radio、Checkboxについて / 5.行列型の編集FORM / 4.サーバーサイドバリデーションとサーバサイド関数 / 3.ログインFORM - S.param使ったら負け / 2.Snippetメソッドとして許される型 / sbt0.12.xで依存jar抽出タスク / scala2.10+lift2.5+NetBeans7.2 / Scalaで入門関数プログラミング / reactive-webを試してみました / Lift2.2M1のテンプレート機能 / Scala Compiler Plugin / View Bound/Context Bound / ScalaZa01参加してきました / Akka Frameworkチュートリアルの次 / Akka Frameworkチュートリアルその2 / Akka Frameworkチュートリアル / LiftでJCaptcha / Url Rewrite Filter / sbt-android-plugin / Android SDK for Scala / 祝Lift2.0リリース / Liftの携帯対応まとめ / Scala2.8への移行 / Lift 2.0-scala280-SNAPSHOT/sbt0.7.1 / Scalaお絵かき環境 - Kojo / Lift+Quartzでバッチ / Scala&Liftを採用した理由 / Liftでdate_select系ヘルパーを作る / LiftでAjax / LiftのSubmitかしこい / lift-mapperのpaginateを使う / snippetをspecする / Lift Mapperを拡張する / LiftのDBをMySQLに / Liftプロジェクト環境を整える / Scala本読み比べてみました / NetBeans6.7&scala / じつはScalaはライトな言語 / Scalaバザ~ル / lift1.0所感 / specsを読む / implicit def / ScalaならNetBeansがサイコー / scala勉強会@東北がスタート / それでも俺はLiftをやるってのか / Scala&Liftセットアップ / ブログリニューアル /
コメント

コメントしてください

closed.