Develop with pleasure!

福岡でCloudとかBlockchainとか。

Specs2で事前処理&事後処理

Play2 Scalaのデフォルトのテストの仕組みSpecs2。
etorreborre/specs2 @ GitHub

specsからspecs2になって結構仕様が変ってて、specs2に移行するにはA++ [Eric Torreborre's Blog]: specs2 migration guideが参考になる。
各Spec実行時の事前処理、事後処理の仕組みも変ってるので、そこだけざっとまとめてみる。

doBefore、doAfterの変更点

事前処理、事後処理の実装方法は何通りかある。

specsのdoBeforeはspecs2では↓のように書ける。

import org.specs2.mutable.Specification
import org.specs2.specification.Scope

class SampleSpec extends Specification{

  "Sample" should {
    "say hello" in new scope{
      val sample = new Sample
      sample.hello must beEqualTo("hello")
    }
  }

  trait scope extends Scope{
    // 前処理を実装
  }
}

事前処理を適用したいinの部分に事前処理を実装したtraitを適用する。
specs2では事前処理、事後処理共に基本的にtraitで実装するみたい。ちなみにdoAfterは↓。

import org.specs2.mutable.{After, Specification}
import org.specs2.specification.Scope

class SampleSpec extends Specification{

  "Sample" should {
    "say hello" in new scope{
      println("say exec")
      val sample = new Sample
      sample.hello must beEqualTo("hello")
    }
  }

  trait scope extends Scope with After{
    // 事前処理

    def after = {
      // 事後処理
    }
  }
}

org.specs2.mutable.Afterというtraitがあるのでそいつを継承する。そうするとafterという関数を実装する必要が出てくるのでそこに事後処理を実装する。

traitを指定しないパターン

↑の方法だとinで事前・事後処理を実装したtraitを指定する必要があったけどSpec自体に事前・事後処理のtraitを実装すると、そのSpec内の全てのテストケースに事前・事後処理が有効になる。

import org.specs2.mutable.Specification
import org.specs2.specification.{BeforeExample, AfterExample, Scope}

class SampleSpec extends Specification with BeforeExample with AfterExample{

  def before = {
    // 事前処理
  }

  def after = {
    // 事後処理
  }

  "Sample" should {
    "say hello" in {
      println("say exec")
      val sample = new Sample
      sample.hello must beEqualTo("hello")
    }
  }

}

全てのSpecに適用したい処理とかは予めBeforeExampleとAfterExampleを継承したtraitを作って、そこでbefore/afterを実装し、各Specでそのtraitを継承する感じかなー。