KotlinのJUnitTestにおけるアサーションライブラリはKluentがとても良い感じ
JUnitのアサーションを快適に書きたい
KotlinでUnitTestを書いていて、今までさして調べずメジャーだからと言う理由でHamcrestを使ってたんですが、もともとJavaのライブラリなのでKotlinだと微妙に使いにくい部分がありました。
例えば型判定のアサーションを記述したいときは↓のように書きますが
val value = 10
assertThat(value, `is`(instanceOf(Int::class.java)))
Kotlinではis
が予約語に指定されているため`
で括る必要もあるのと、is
とinstanceOf
がネストしているのも微妙に書きにくい&読みにくく、クラス指定も::class.java
まで記述する必要があって、当たり前ですがKClass
で記述できないのでJavaの世界観に引きづられている印象を受けます。
また細かいところだと、is
メソッド一つとってもHamcrest内だけでも3つimoport
候補が出てきて、どれをimoport
するんだっけ?と一瞬手が止まるのも書きにくいなぁと思っていた部分でした(ここはKotlin関係ない部分ですが)
この辺はイマイチだなーと思いつつプロダクションに入らないコードだし動けばまあいいかと思っていたんですが、Kotlinに特化したアサーションライブラリを試しに使ってみたら思いの外快適に記述できて感動したので紹介します。
Kluent
Docs: https://markusamshove.github.io/Kluent/
Github: https://github.com/MarkusAmshove/Kluent
KluentはKotlinに特化したJunitアサーションライブラリです。
Fluent Assertion-Library for Kotlin
とあるように流れるように記述できるのが特徴です。
Hamcrestがstaticメソッドを軸にアサーションを実装しているのに対し、KluentはKotlinの拡張関数やinfix記法(中置記法)を軸にアサーションが実装されています。
アサーション比較
公式サイトへのリンク先に使い方がわかりやすく乗っているのでぱっと見で理解できるとは思いますが、1例として上記で扱った型判定のアサーションでHamcrestとKluentを比較してみます。
val value = 10
assertThat(value, `is`(instanceOf(Int::class.java)))
val value = 10
value shouldBeInstanceOf Int::class
どうでしょうか、カッコもなくなりだいぶ読みやすく書きやすくなったと思います。
Hamcrestはstaticメソッドである関係上Utilクラスのように手前にassertThat
メソッドを書かなくてはいけませんが、Kluentはinfix記法のおかげで「valueはint型でなければならない」という英文を違和感なく構築することができています。
もちろんinfix記法でも補完が効きます。とりあえずshould...
と打てば必要なものが見つかると思います。
また、infix以外にも拡張関数で定義されたアサーションもあり、nullチェックなどがそれに当たります。
val value = 10
assertThat(value, `is`(notNullValue()))
val value: Int? = 10
value.shouldNotBeNull()
そらで書く場合どちらのほうが記述しやすいかは一目瞭然ですね!
私自身Kluentの基本的な機能しかまだ使っていませんが、サイトのドキュメントを見る限り一般的にアサーションで最低限必要とされるものは揃っていると思います。
モック機能
KluentにはMocking機能があり、サイト内の解説によるとMockito-Kotlinのラッパーとしての役割も担っているそうです。
val mock = mock(Database::class)
mock.getPerson(1)
私はMockKに慣れきっていたので使いませんでしたがMockito-Kotlinを使っている方であれば嬉しいポイントかもしれません。
Androidで使う場合
これは正直ちゃんとはわからなかった部分だったのですが、GithubのドキュメントによるとAndroidで使う場合にはartifactが異なり、以下を指定する必要があるそうです。
// for JVM:
testImplementation 'org.amshove.kluent:kluent:{version}'
// for Android:
testImplementation 'org.amshove.kluent:kluent-android:{version}'
この違いについてはドキュメントには記載がなかったのですが、2020/08/08現在のリポジトリ内をざっくり検索したところライブラリの機能や含まれているソースコード自体には違いはなく、JVMによる実行環境とAndroid上の実行環境の差異を吸収するためにartifactが別れているようでした。
これが正しければですが、Androidデバイス上で実行されるInstrumented Testはorg.amshove.kluent:kluent-android
を使う必要がありますが、Androidのプロジェクトであってもデバイスを伴わずPC上のJVM環境で実行されるUnitTestやRobolectricを使ったテストはorg.amshove.kluent:kluent
で十分と思われます。
まとめ
Kluentはいいぞ!
Author And Source
この問題について(KotlinのJUnitTestにおけるアサーションライブラリはKluentがとても良い感じ), 我々は、より多くの情報をここで見つけました https://qiita.com/KazaKago/items/bb4111aa154e00f27673著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .