
みなさまこんにちは〜!
メモリアインクのすだです。
今回は、Androidアプリ開発におけるJUnit5を使ったテストにおいて
MockKをどのように利用するかについて解説していきます。
この記事を読んでわかること…
・MockKとは?「モック」の必要性
・MockKの基本構文
・MockKを使った実践的なテスト方法
JUnit5を使用した基本的なテストの方法に関しては、以下の記事で詳しくご紹介しています。
ぜひ併せてご覧ください。


環境
- Kotlin (ver 1.9.0)
- Android Studio (Giraffe | 2022.3.1 Patch 3)
MockKとは?
ユニットテスト(単体テスト)では、「テスト対象以外の部分を置き換える仕組み(=モック)」が重要です。
たとえば、以下のようなケースです:
- ViewModelの中でRepositoryを使っている
- でもテスト時には、Repositoryの中身(DBやAPI通信)は動かしたくない
こういうときに「モック」が便利です。
MockKは、Kotlin専用のモックライブラリなので モックの作成や管理に非常に役立ちます。
https://mockk.io/
MockKの導入時は、以下をGradleに追加してください。
testImplementation("io.mockk:mockk:1.13.5")
MockKの使い方の基礎
1. モックの生成
val repository = mockk<UserRepository>()
mockk<オブジェクトの型>()
と書くことで、
指定したクラス(型)の「偽物インスタンス(モック)」を作る宣言をすることができます。
通常の UserRepository
ならAPI通信やDBアクセスをしてしまいますが、
モックにすることで テスト時にそれらを実行せず、好きな戻り値を返せます。
2. モックの挙動を定義(every)
every { repository.fetchUserName() } returns "テストユーザー"
every { ... }
は「この呼び出しがあったときに」returns ...
は「この値を返してね」という意味です。
つまり、モックがどう振る舞うかを事前にプログラムしておく構文です。
ここでは、repository.fetchUserName()
がテスト中に呼ばれたら"テストユーザー"
を返すようにモックの振る舞いを指定しています。
この every { ... } returns ...
がないと、モックは何も返せません。
テスト中に呼ばれても null
や例外が返ってしまいます。
3. 実際に呼び出されたかを確認(verify)
verify { repository.fetchUserName() }
verify { … }
と書くことで、
「本当にこの関数が呼ばれたか?」を確認して、処理が期待通りに動いたか検証することができます。
ここでは、fetchUserName()
が1回は呼ばれたことをチェックしており
もしこれが仮に呼ばれていなかったとするとテスト失敗になりエラーが出力されます。
MockKの基本構文を使ったテスト全体像
基本構文を使ったテストコードの全体像は以下です。
テスト対象のViewModel(例)▼
class ProfileViewModel(private val repository: UserRepository) {
fun getGreeting(): String {
val name = repository.fetchUserName()
return "こんにちは、${name} さん!"
}
}
テストコード全体(MockK+JUnit5)▼
class ProfileViewModelTest {
@Test
fun `ユーザー名が反映された挨拶が返る`() {
// モックの生成
val repository = mockk<UserRepository>()
// モックの挙動を定義(この関数が呼ばれたらこの値を返す)
every { repository.fetchUserName() } returns "サトウ"
// ViewModelにモックを注入
val viewModel = ProfileViewModel(repository)
// テスト対象の関数を実行
val result = viewModel.getGreeting()
// 結果の確認(アサーション)
assertEquals("こんにちは、サトウ さん!", result)
// 実際に呼び出されたかを確認(検証)
verify { repository.fetchUserName() }
}
}
モックの生成と挙動の定義が完了したら、
生成したモックを ProfileViewModel
の引数に渡し、テストの中で getGreeting()
を呼び出します。
assertEquals
を使ってメソッドの返り値が期待通りかどうかを検証し、
さらに verify { ... }
を使うことで、モックの関数が実際に呼び出されたかを確認できます。
アノテーションを使ったモックの定義(@MockK)
MockKでは mockk<>()
を使う以外にも、アノテーション(@MockK)を使ってモックを生成する方法もあります。
これは、JUnitの @BeforeEach
などと組み合わせることで、
複数のモックを自動的に初期化できる便利なスタイルです。
class ProfileViewModelTest {
@MockK
lateinit var repository: UserRepository
lateinit var viewModel: ProfileViewModel
@BeforeEach
fun setUp() {
// モックを初期化
MockKAnnotations.init(this)
viewModel = ProfileViewModel(repository)
}
@Test
fun `ユーザー名が反映された挨拶が返る`() {
every { repository.fetchUserName() } returns "サトウ"
val result = viewModel.getGreeting()
assertEquals("こんにちは、サトウ さん!", result)
verify { repository.fetchUserName() }
}
}
MockK
アノテーションは、モック化したいプロパティに付与します。
(あとで自動で初期化するため、プロパティはlateinitにしておきます)
ここで重要なのは、MockKでは @MockK
を付けただけではモックは自動生成されないという点です。
そのため、MockKAnnotations.init(this)
を呼び出して、@MockK
アノテーションが付与されたすべてのプロパティに対して、モックの生成と初期化を行う必要があります。
これを行わないと、repository は null のままとなり、lateinit property repository has not been initialized
という例外が発生します。
また、この初期化処理は @BeforeEach
アノテーションを使って定義することで、
各テストごとにクリーンな状態で repository
を初期化し、それを使って ProfileViewModel
を生成できるようになります。
まとめ
おつかれさまでした。いかがでしたでしょうか!
MockKを使えば、外部依存を切り離して本当にテストしたいロジックに集中できます。
この記事の方法で、ViewModelやUseCase、非同期処理のテストまで幅広く対応できます。
次は、非同期処理(コルーチン)やFlowのモックテストにも挑戦してみましょう〜▼





技術者としてのキャリアパスを次のレベルへと進めたい皆様、
未経験からIT・Webエンジニアを目指すなら【ユニゾンキャリア】
自分の市場価値をさらに向上させてみませんか?
それではまた次の記事でお会いしましょう!
コメント