Specs2を試す(8)
Single step
Given/When/Then の3つのステップは GivenThen で1つにまとめることができる。
import org.specs2._ import specification._ class GivenThenSpec extends Specification { def is = "given the name: ${eric}, then the age is ${18}" ! new GivenThen { def extract(text: String) = { val (name, age) = extract2(text) age.toInt must_== 18 } } }
so オブジェクトを使う手もある。これは GivenThen を作るためのショートカットのようなもの。
次のように定義してある。
// specs2/src/main/scala/org/specs2/specification/RegexStep.scala object so { def apply[R <% Result](f: PartialFunction[Any, R]): GivenThen = new GivenThenFunction(f) }
apply メソッドが PartialFunction を引数にとって GivenThen を返してくれている。
import org.specs2._ import specification._ class GivenThenSpec extends Specification { def is = "given the name: ${eric}, then the age is ${18}" ! so { case (name: String, age: String) => age.toInt must_== 18 } }
Conversions
Given/When/Then ステップは型パラメータに対してinvariant(不変)。これは再利用の点で問題になることがある。
例えば Then[X] というステップを定義し、後に X のサブクラスである Y に対し、 Then[Y] を定義したくなったときはどうするか。
以下のコードが意味を成すような場合、implicit conversion を定義してやることでうまく対処できる。*1
val thenX = new Then[X] { def extract(x: X, s: String) = success // x に対してのテスト } // Y <: X を thenX を Then[Y] ステップとして再利用できる val thenY: Then[Y] = thenX
*1:らしいんだけど、ここらへん実例とかが見つからず理解が不十分...