Truthのカスタムサブジェクトを定義する
目次
Truthのカスタムサブジェクトを新たに定義して、独自のアサーションを追加してみます。公式の解説を参考に進めました。Javaで書かれたサンプルコードをKotlinに読み替えるのに若干の苦労をしましたが、なんとかなりました。
今回は、サンプルとしてKotlinのUnit型に対するアサーションを追加します。つまり、以下のようなアサーションができるようにします。
@Test
fun test_isNotUnit() {
val actual: Unit? = null
assertThat(actual).isNotUnit()
}
@Test
fun test_isUnit() {
val actual: Unit? = Unit
assertThat(actual).isUnit()
}
余談ですが、KotlinのUnitのインスタンスをJavaで使うには、 Unit.INSTANCE
と書くことを知りました。またひとつ賢くなりました。
カスタムサブジェクトの定義
com.google.common.truth.Subject
(以下Subjectと呼ぶ)を継承して、カスタムサブジェクトを作ります。Subjectのコンストラクタは、引数としてFailureMetadataと検査対象となるObjectをとります。カスタムサブジェクトのコンストラクタ引数もこれに準じます。コンストラクタはprivateにしておきます(理由は後述します)。
class UnitSubject private constructor(
metadata: FailureMetadata,
private val actual: Unit?,
) : Subject(metadata, actual) {
// TODO
}
次に、 assertThat
をstaticな関数として定義します。 assertThat
は検査対象となる値(actual)を引数にとります。この中で呼んでいる assertAbout
はSubjectのFactoryを引数にとり、SubjectBuilderを返します。さらにSubjectBuilderに対して that
を呼び出し、actualを渡すことでSubjectが作られます。ここでは独自に定義したUnitSubjectを返しています( assertThat
を経由してUnitSubjectのインスタンスを作りたいため、コンストラクタをprivateにしています)。
class UnitSubject private constructor(
metadata: FailureMetadata,
private val actual: Unit?,
) : Subject(metadata, actual) {
// TODO
companion object {
/**
* start assertion of an object with type Unit?
*/
fun assertThat(actual: Unit?): UnitSubject = assertAbout(unit()).that(actual)
private fun unit(): Factory<UnitSubject, Unit?> = Factory(::UnitSubject)
}
}
UnitSubjectにアサーションを実装します。今回はSubjectに生えている isEqualTo
と isNotEqualTo
を使うだけで済みました。
class UnitSubject private constructor(
metadata: FailureMetadata,
private val actual: Unit?,
) : Subject(metadata, actual) {
/**
* assert that actual is Unit.
*/
fun isUnit() = unit().isEqualTo(Unit)
/**
* assert that actual is NOT Unit.
*/
fun isNotUnit() = unit().isNotEqualTo(Unit)
private fun unit(): Subject = check("unit()").that(actual)
// 省略
}
カスタムサブジェクトを用いたアサーション
カスタムサブジェクトを用いてアサーションをしてみます。
package com.okuzawats.truth
import com.okuzawats.truth.UnitSubject.Companion.assertThat
import org.junit.Test
class UnitTest {
@Test
fun test_isNotUnit() {
val actual: Unit? = null
assertThat(actual).isNotUnit()
}
@Test
fun test_isUnit() {
val actual: Unit? = Unit
assertThat(actual).isUnit()
}
}
動きました🎉
ソースコード
Truthのバージョンは1.1.3を用いています。
package com.okuzawats.truth
import com.google.common.truth.FailureMetadata
import com.google.common.truth.Subject
import com.google.common.truth.Subject.Factory
import com.google.common.truth.Truth.assertAbout
class UnitSubject private constructor(
metadata: FailureMetadata,
private val actual: Unit?,
) : Subject(metadata, actual) {
/**
* assert that actual is Unit.
*/
fun isUnit() = unit().isEqualTo(Unit)
/**
* assert that actual is NOT Unit.
*/
fun isNotUnit() = unit().isNotEqualTo(Unit)
private fun unit(): Subject = check("unit()").that(actual)
companion object {
/**
* start assertion of an object with type Unit?
*/
fun assertThat(actual: Unit?): UnitSubject = assertAbout(unit()).that(actual)
private fun unit(): Factory<UnitSubject, Unit?> = Factory(::UnitSubject)
}
}
GitHubのpublicリポジトリにもソースコードを公開します。
References
- Extensions to Truth (最終アクセス日:2023年3月25日)
- okuzawats/android-truth-samples: アサーションライブラリ Truth の使い方のサンプル (最終アクセス日:2023年3月25日)
書いている人 😎

茨城県つくば市在住のモバイルアプリケーションアーキテクト(Androidが得意です)。モバイルアプリのアーキテクチャ、自動テスト、CI/CDに興味があります。いわゆる「レガシーコード」のリファクタリング・リアーキテクチャが好きです。
👉 もっと詳しく
著書 ✍
Android 依存性注入 ヒッチハイク・ガイド🧳
Androidアプリでの依存性注入(Dependency Injection)に入門するためのガイダンスです。依存性注入の概念やメリットを理解し、Dagger Hiltを用いてAndroidアプリに適用する方法を解説しています。
ソフトウェアデザイン 2023年6月号📚
特集「クリーンアーキテクチャとは何か?」の第5章「モバイルアプリ開発における実践」を執筆しました。
Android クリーンアーキテクチャ ヒッチハイク・ガイド🧳
Androidアプリでのクリーンアーキテクチャに入門するためのガイダンスです。クリーンアーキテクチャの概念を理解し、Androidアプリに適用する方法を解説しています。
Android ユニットテスト ヒッチハイク・ガイド🧳
Androidアプリのユニットテストに入門するためのガイダンスです。初学者が混乱せずにAndroidアプリのユニットテストを書き始めることができる、ということを目的としています。
Android MVVMアーキテクチャ入門🛠
Androidアプリ開発の初学者に向けた、MVVM(Model-View-ViewModel)アーキテクチャの入門書を書きました。初学者の方を確実にネクストレベルに引き上げる技術書です。NextPublishingより出版されています。
関連記事 👀
- Mockk によるモック入門
- Truth によるアサーション入門
- 「Android ユニットテスト ヒッチハイク・ガイド」を頒布します
- [Android] Robolectricとandroidx.test
- [Android] OkHttpのMockWebServerを用いた、OkHttp + Retrofitのユニットテスト