Kotlin+SparkでWEBアプリを作ってテストを書く

JVMで動く軽量なマイクロフレームワークであるSparkをKotlinで動かし、ルーティングのテストも書きます。

## Sparkとは
[公式サイト](http://sparkjava.com/)によると```
A micro framework for creating web applications in Kotlin and Java 8 with minimal effort
```
をコンセプトにした、JavaおよびKotlinで利用できる軽量なWEBアプリケーションフレームワークです。
Javaで動くFWといえばSpringなどが定番かと思いますが、Sparkは最低限の機能のみを実装しているマイクロフレームワークに分類されるフレームワークです。
RubyのSinatraにインスパイアされているらしく、実際にSinatraと非常によく似た使い勝手です。
簡単なWEBアプリならほんの数分で実装可能です。

## SparkでHelloWorld
まずはSparkで超簡単なアプリを作成します。[公式サイト](http://sparkjava.com/)を参考に以下の手順で実装します。

### Gradleの設定
build.gradleに以下を追記します。

``` 
compile "com.sparkjava:spark-kotlin:1.0.0-alpha"
```

### Appの実装
アプリの本体をKotlinで記述します。

```Kotlin:src/main/App.kt
import spark.Spark.*

fun main(args: Array<String>) {
    get("/", (req, res) -> "Hello World");
}

```

これだけで実装は完了です。本当にSinatraにそっくりだ。。。

### 実行
SparkにはJettyサーバーが含まれているので、App.ktを実行するだけでアプリが起動します。
サーバーが起動したら以下のURLにアクセスします。

```
http://localhost:4567
```
無事に"Hello Wolrd"が表示されれば終わりです。簡単。

## テストを書いてみる
ルーティングを増やすたびに人力で確認するのもアレなので、テストを書いてみます。
ググってみるといろいろなやり方が見つかりますが、RubyとSinatraで書いていたようなやり方を試してみます。
参考にしたのは[stackoverflowのこちらの記事](https://stackoverflow.com/a/42776601)です。
サーバーを起動し、ApacheのHttpClientで指定のパスにアクセスしてレスポンスを検証します。

### Gradleの設定
build.gradleに以下を追加

```
testCompile group: 'junit', name: 'junit', version: '4.12'
testcompile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5'
```

### テストの記述
以下のようにテストを実装します。

```kotlin:src/test/AppTest.kt

import org.junit.After
import org.junit.Before

import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader

import junit.framework.TestCase.assertEquals
import org.apache.http.HttpResponse
import org.apache.http.client.methods.HttpGet
import org.apache.http.impl.client.HttpClients
import org.junit.Test

import spark.Spark

class SparkTest {

    private val httpClient = HttpClients.custom().build()
    private val serverHost = "http://localhost"
    private val serverPort = "4567"


    private fun url():String {
        return serverHost + ":" + serverPort
    }

    private fun get(path:String) :HttpResponse　{
        val httpGet = HttpGet(url() + path)
        return httpClient.execute(httpGet)
    }

    @Before
    fun setup() {
        // Appを起動
        main(Array(0, {_ -> ""}))
        Thread.sleep(1500)
    }

    @After
    @Throws(Exception::class)
    fun tearDown() {
        // Appを停止
        Thread.sleep(1000)
        Spark.stop()
    }

    @Test
    @Throws(IOException::class)
    fun testRooting() {
        val response = get("/")

        val statusCode = response.statusLine.statusCode
        val rd = BufferedReader(InputStreamReader(response.entity.content))

        val result = StringBuffer()
        var line = rd.readLine()
        do {
            result.append(line)
            line = rd.readLine()

        } while (line != null)

        assertEquals(200, statusCode)
        assertEquals("Hello World", result.toString())
    }
}
```
アプリケーションのルートにGetでアクセスして、レスポンスのステータスコードと本体をチェックしているだけです。

### テストの実行
上記のテストを実行し、グリーンバーが出ればOKです。

## まとめ
KotlinでSparkを動かしている記事はそれなりに見つかりますが、日本語でテストまで言及している記事があまり見つからなかったので、自分用にまとめました。

Kotlinで使えるマイクロフレームワークといえばJetBrains謹製の[Ktor](http://ktor.io/)などもあります。

ただKtorはまだまだ発展途上で公式のドキュメントすらスカスカ状態なので、
今Kotlinで簡単なwebアプリを作るならSparkはなかなか良い選択肢なのではないかと思いました。

強いて言うならApacheのSparkと名前が被っているのでググラビリティが低いのが欠点といえば欠点でしょうか。
あと日本語の情報がそこまで多く無い気がしたので、あまり日本では人気がないのかな？Java界に詳しくないのでよくわかりませんが。。


## 参考
[http://sparkjava.com/](http://sparkjava.com/)
[Spark web framework unit tests](https://stackoverflow.com/questions/31076855/spark-web-framework-unit-tests)
[KotlinとSparkでWebアプリケーション①（準備とHello World!編）](https://qiita.com/naoi/items/1d56d571881ad685fd8a)