Spockでテストコードを書くとき、1つのメソッドに対してテストケースが複数ある場合、whereブロックを使ってまとめて書けるとスッキリして見やすくなる。
before
def "StringUtils#split()"() {
when:
def result1 = StringUtils.split("a")
then:
result1.size() == 1
when:
def result2 = StringUtils.split("a b c")
then:
result2.size() == 3
}
after
def "StringUtils#split()"() {
when:
def result = StringUtils.split(str)
then:
result.size() == size
where:
str || size
"a" || 1
"a b c" || 3
}
が、場合によってはwhereブロックでは表現できないケースもある。例えばメソッドの戻り値がnullの場合とそうでない場合とで判定を分けたい、とか。
if文とかで分岐させりゃいいのか?、と思ってやってみる。
def "StringUtils#split()"() {
when:
def result = StringUtils.split(str)
then:
if (result != null) {
result.size() == size
}
where:
str || size
"a" || 1
"a b c" || 3
null || null
}
テストは成功するのでめでたしめでたし、と思いきや、whereブロックのsizeの値が正しくなくてもテストは成功してしまう。if文じゃなくてswitch文とかでも同じ。
where:
str || size
"a" || 11
"a b c" || 33
null || null
危険!
このような場合は明示的にassert
を使用することで正しく動作する。
then:
if (result != null) {
assert result.size() == size
}
あるいは、三項演算子を使うという手も、なくはない。
then:
result != null ? result.size() == size : true
これでも一応ちゃんと判定はしてくれる。
見やすいか見にくいかは、あなた次第。
なお、使用したSpockのバージョンは1.3。