ついに Kotlin 1.0 がリリースされました。
テストや Spec を書こうと思った場合、Groovy には Spock という強力なフレームワークがありました。
Kotlin では Spek を使用します。
環境
- Maven 3.3.3
- Java 1.8.0_45
- Kotlin 1.0.0
- Spek 0.1.195
$ mvn --version
Apache Maven 3.3.3 (7994120775791599e205a5524ec3e0dfe41d4a06; 2015-04-22T20:57:37+09:00)
Maven home: /usr/local/Cellar/maven/3.3.3/libexec
Java version: 1.8.0_45, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/jre
Default locale: ja_JP, platform encoding: UTF-8
OS name: "mac os x", version: "10.10.3", arch: "x86_64", family: "mac"
Spek
Spek は非常にシンプルなテスティングフレームワークで、Spock とは異なり、given
on
it
の3種類のブロックしか出てきません。
それぞれには以下の役割があります。
ブロック | 役割 |
---|---|
given | セットアップ。テストターゲットのインスタンス生成や、パラメタ、期待値の準備など。 |
on | アクション。テストターゲットの実行。 |
it | アサーション。 |
より具体的なサンプルは Spek のドキュメントをどうぞ。
http://spekframework.org/docs/latest/
where
さて、ここで問題に気付きます。
Spek には、Spock でテストを見通し良くするのに貢献していた where
に相当するブロックがありません。
存在しないからには、なにか理由があるはずです。
考えた結果、おそらく その答えは Kotlin の表現力の高さにあります。
以下、FizzBuzz を例にとって、where
に相当するコードを Kotlin、Spek で記述してみます。
全てのコード。
https://github.com/yo1000/fizzbuzz-kotlin.git
テストターゲット。
class FizzBuzz() {
fun fizz(value: Int): String {
return if (value % 3 == 0) "fizz" else ""
}
fun buzz(value: Int): String {
return if (value % 5 == 0) "buzz" else ""
}
fun fizzBuzz(value: Int): String {
val builder = StringBuilder(fizz(value)).append(buzz(value))
return if (builder.isEmpty()) value.toString() else builder.toString()
}
}
テスト。
import org.jetbrains.spek.api.Spek
import kotlin.test.assertEquals
data class Params(val value: Int)
data class Expects(val fizz: String, val buzz: String, val fizzBuzz: String)
class FizzBuzzTest: Spek() {
init {
given("fizzBuzz") {
val fizzBuzz = FizzBuzz()
listOf(
Params( 3) to Expects("fizz" , "" , "fizz" ),
Params( 5) to Expects("" , "buzz", "buzz" ),
Params(15) to Expects("fizz" , "buzz", "fizzbuzz"),
Params( 4) to Expects("" , "" , "4" )
).forEach {
val (param, expect) = it
on("fizzbuzz param=${param.value}") {
val fizz = fizzBuzz.fizz(param.value)
val buzz = fizzBuzz.buzz(param.value)
val fizzBuzz = fizzBuzz.fizzBuzz(param.value)
it ("${expect.fizz}=${fizz}") {
assertEquals(expect.fizz, fizz)
}
it ("${expect.buzz}=${buzz}") {
assertEquals(expect.buzz, buzz)
}
it ("${expect.fizzBuzz}=${fizzBuzz}") {
assertEquals(expect.fizzBuzz, fizzBuzz)
}
}
}
}
}
}
テスト結果。

Kotlin の data
listOf
to
val (a, b) = p
を使用することで、かなり where
表現に近づけたのではないかと思います。
この表現力の高さゆえ Spek では、あえて where
に相当するブロックが用意されていないのではないかと思いました。