LoginSignup
9
11

More than 5 years have passed since last update.

Kotlin Spek で Groovy Spock where のようなテスト

Last updated at Posted at 2016-02-27

ついに 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

テストターゲット。

FizzBuzz.kt
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()
    }
}

テスト。

FizzBuzzTest.kt
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)
                    }
                }
            }
        }
    }
}

テスト結果。

スクリーンショット 2016-02-28 0.00.11.png

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

9
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
11