Specs2を試す(4)
参考: http://etorreborre.github.com/specs2/guide/org.specs2.guide.SpecStructure.html#Declare+examples
Result
// コード1 "this is my specification" ^ "and example 1" ! e1^ "and example 2" ! e2 def e1 = success def e2 = success
上の例の
"and example 1" ! e1^
この部分は、description ! body という形になっていて、
bodyの部分は Result(org.specs2.executable.Result) を返す。
このResultには3つのタイプがあって、それは
- a standard result
- a Matcher result
- a boolean value
Standard results
これは一番単純なResultの値。StandardResultsトレイトによって提供されている。
ソースを見ればああなるほどってなる。
// コード2: specs2/src/main/scala/org/specs2/execute/StandardResults.scala package org.specs2 package execute /** * This trait provides standard results which can be used in Fragments bodies */ trait StandardResults { def done = Success("DONE") def wontdo = Success("WONT DO") def todo = Pending("TODO") def pending = Pending("PENDING") def anError = Error("error") def success = Success("success") def failure = Failure("failure") def skipped = Skipped("skipped") } object StandardResults extends StandardResults
例えばすでにsuccessとか使ってたけどこれは実はResultのサブクラスのSuccessクラスのインスタンスを返していたわけだ。
Matcher results
例えばこんなの
1 must_== 1
こいつはほかにも大量にある。
- Matchers for Any
- Option / Either matchers
- String matchers
- Numeric matchers
- Exception matchers
- Iterable matchers
- Map matchers
- Xml matchers
- Json matchers
- File matchers
- Scalaz matchers
- Result matchers
- Interpreter matchers
- Parsers matchers
いろいろありすぎてめんどいので細かく見ていくのはまた今度ということで。
Functional expectations
specs2っていうかScalaは関数の中で評価された最後の式が返り値になる。
だから次のようなことが起こる。
// コード3 "my example on strings" ! e1 // 結果はsuccess def e1 = { "hello" must have size(10000) // <- ここの結果は返らない!! "hello" must startWith("hell") // <- ここの結果が返る }
これを防ぐには例えば次のように and を使う。
// コード4 "my example on strings" ! e1 // 結果はfailure def e1 = "hello" must have size(10000) and startWith("hell")
Thrown Expectations
コード4 のような書き方のほかに org.specs2.matcher.MustThrownMatchers トレイトを使えば、
1つ目の式が失敗した時点で FailureException を飛ばして終了させることができる。
こんな風に使う。
// コード5 "my example on strings" ! e1 // 結果はFailure def e1 = new Scope extends MustThrownMatchers { "hello" must have size(10000) // <- ここで FailureException が飛ぶ "hello" must startWith("hell") // <- ここはスルー }
それから FailureException を飛ばす failure(message) っていうメソッドもある。
// コード6 "my example on strings" ! e1 // 結果はFailure def e1 = new Scope extends MustThrownMatchers { failure("うつだしのう...") // <- ここで FailureException が飛ぶ "hello" must startWith("hell") // <- ここはスルー }
org.specs2.specification.Scope は trait で Success に暗黙変換される。そんな便利なやつ。