Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

ついに 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 に相当するブロックが用意されていないのではないかと思いました。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした