MockK(モックケー)は、Kotlin 用のモックライブラリです。 「every { 呼び出し } returns 値 で振る舞いを決め、verify { 呼び出し } で呼ばれたかを確かめる」のが基本です。

val repo = mockk<UserRepository>()

every { repo.findById(1) } returns User(1, "Ito", "ito@example.com")

repo.findById(1)            // User(1, "Ito", ...)

verify { repo.findById(1) }
やりたいこと 書き方
モックを作る mockk<T>()
何でも適当な値を返すモック mockk<T>(relaxed = true)
戻り値を決める every { m.f(1) } returns x
例外を投げる every { m.f(1) } throws E()
引数で答えを変える every { m.f(any()) } answers { firstArg() }
戻り値が Unit の関数 justRun { m.g(any()) }
呼ばれたか確かめる verify { m.f(1) }、回数は verify(exactly = 2)
引数を取り出す val s = slot<T>() → capture(s) → s.captured
suspend 関数 coEvery { … }・coVerify { … }
object・トップレベル関数 mockkObject(Obj)・mockkStatic(::func)

MockK のモックは既定で「厳格(strict)」です。 every を書いていない呼び出しは、適当な値を返さずに MockKException: no answer found for … で止まります。ここが Mockito(既定で null や 0 を返す)との一番大きな違いです。

確認環境:MockK 1.14.11(GitHub のリリース一覧で最新の版。2026年5月29日公開)。API・既定値・エラー文は、mockk.io のドキュメント(GitHub の README)と、タグ v1.14.11 のソースコードで確かめました。Kotlin が「関数をどんな Java のクラスやメソッドに変えるか」と、Mockito 流の書き方で起きる NullPointerException は、kotlinc 2.4.20(OpenJDK 21.0.10、Linux)で再現しました(確認日 2026年10月12日)。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「MockK 使い方|every・verify・coEveryとMockito対応表」

依存の書き方

Gradle(build.gradle.kts)

plugins {
    kotlin("jvm") version "2.4.21"
}

repositories {
    mavenCentral()
}

dependencies {
    testImplementation(kotlin("test"))
    testImplementation("io.mockk:mockk:1.14.11")
    // suspend 関数のテストを runTest で書くとき
    testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.11.0")
}

tasks.test {
    useJUnitPlatform()
}

Maven・Android

使う場所 依存
Maven io.mockk:mockk-jvm(scope は test)
Android の単体テスト testImplementation "io.mockk:mockk-android:…" と io.mockk:mockk-agent
Android の計装テスト androidTestImplementation で同じ2つ
Spring Boot の @MockkBean com.ninja-squad:springmockk(5.x が Spring Boot 4 向け)

ドキュメントでは「MockK 1.13.0 から Kotlin 1.4 以上に対応」とあります。suspend 関数のモック(coEvery)には kotlinx-coroutines-core が要りますが、テストで runTest を使うなら kotlinx-coroutines-test が kotlinx-coroutines-core を連れてきます。

Gradle の書き方の対訳は、関連記事「build.gradle書き方|Groovy/Kotlin DSL対訳と依存設定一覧」で扱っています。

この記事で使うテスト対象のコード

data class User(val id: Long, val name: String, val email: String)

interface UserRepository {
    fun findById(id: Long): User?
    fun save(user: User): User
}

interface MailSender {
    fun send(to: String, body: String)
}

interface ProfileApi {
    suspend fun fetchNickname(id: Long): String
}

object IdGenerator {
    fun next(): Long = System.nanoTime()
}

class UserService(
    private val repo: UserRepository,
    private val mail: MailSender,
    private val api: ProfileApi,
) {
    fun register(name: String, email: String): User {
        val user = repo.save(User(IdGenerator.next(), name, email))
        mail.send(email, "ようこそ $name さん")
        return user
    }

    fun rename(id: Long, newName: String): User {
        val user = repo.findById(id) ?: throw NoSuchElementException("user $id")
        return repo.save(user.copy(name = newName))
    }

    suspend fun nickname(id: Long): String =
        api.fetchNickname(id).ifBlank { "名無し" }
}

モックの作り方:mockk・relaxed・spyk・mockkObject・mockkStatic

関数 何ができるか 使う場面
mockk<T>() 厳格なモック。every の無い呼び出しは例外 基本はこれ
mockk<T>(relaxed = true) すべての関数が「適当な値」を返す 戻り値に興味の無い依存
mockk<T>(relaxUnitFun = true) 戻り値が Unit の関数だけ何もしない ログ・通知など副作用だけの依存
spyk(obj)・spyk<T>() 本物の処理を呼びつつ、一部だけ差し替える 本物の大半を使いたいとき
mockkObject(Obj) Kotlin の object をモックにする シングルトンを差し替える
mockkStatic(::func)・mockkStatic("pkg.FileKt") トップレベル関数・拡張関数を差し替える ファイル直下の関数
mockkConstructor(T::class) T(...) で新しく作られたものを差し替える コードの中で new しているもの

relaxed と relaxUnitFun

val mail = mockk<MailSender>(relaxUnitFun = true)
mail.send("a@example.com", "hi")   // 何もせずに戻る(every 不要)
verify { mail.send("a@example.com", "hi") }

relaxed = true は、ドキュメントでは「すべての関数が単純な値を返す。参照型には、連鎖したモックを返す」とされています。ジェネリクスの戻り値とは相性が悪く、ClassCastException になることが多いとも書かれていて、その場合は手で every を書くよう案内されています。

relaxed は便利ですが、every の書き忘れに気づきにくくなります。 戻り値を使う依存には厳格なモック、通知のように Unit を返すだけの依存には relaxUnitFun と分けると、書き忘れを見つけやすくなります。

spyk:本物を呼びつつ一部だけ差し替える

val calc = spyk(Calculator())
every { calc.tax(any()) } returns 0     // tax だけ差し替え
calc.total(1000)                         // total の中身は本物
verify { calc.tax(1000) }

ドキュメントの注意点は2つです。spyk(obj) は渡したオブジェクトのコピーで、元のオブジェクトは変わりません。suspend 関数をスパイすると、予想外の結果になる既知の問題があります(issue #554)。

mockk で作ったモックでも、answers { callOriginal() } と書いた呼び出しだけは本物を呼べます。

mockkObject・mockkStatic が要る理由(kotlinc で確認)

Kotlin の object やトップレベル関数は、普通の mockk<T>() では差し替えられません。Java のクラスとしては static なものになっているからです。次のコードをコンパイルし、javap でできたクラスを見ました。

// Repo.kt(package demo)
object IdGenerator { fun next(): Long = 1L }
fun formatName(name: String): String = name.uppercase()
fun String.masked(): String = take(1) + "***"
interface UserApi { suspend fun fetch(id: Long): String }
public final class demo.IdGenerator {
  public static final demo.IdGenerator INSTANCE;
  public final long next();
}
public final class demo.RepoKt {
  public static final java.lang.String formatName(java.lang.String);
  public static final java.lang.String masked(java.lang.String);
}
public interface demo.UserApi {
  public abstract java.lang.Object fetch(long, kotlin.coroutines.Continuation<? super java.lang.String>);
}
Kotlin で書いたもの Java から見た形 MockK での差し替え
object IdGenerator static の INSTANCE が1つだけ mockkObject(IdGenerator)
トップレベル関数(Repo.kt) RepoKt クラスの static メソッド mockkStatic(::formatName) か mockkStatic("demo.RepoKt")
トップレベルの拡張関数 同じく RepoKt の static メソッド。受け手は第1引数 mockkStatic(String::masked) か mockkStatic("demo.RepoKt")
suspend fun fetch(id: Long) 引数に Continuation が1つ増える coEvery・coVerify

ファイル名 + Kt がクラス名になるので、mockkStatic に文字列で渡すときは "パッケージ名.ファイル名Kt" と書きます。ドキュメントによると、@file:JvmName("KHttp") のように名前を変えていればその名前を使い、関数参照で渡してもそのファイルのクラス全体がモックになります。

mockkObject(IdGenerator)
every { IdGenerator.next() } returns 100L

mockkStatic(::formatName)
every { formatName("ito") } returns "ITO!"

object と static のモックは、テストが終わっても残ります。 unmockkObject(IdGenerator)・unmockkStatic(...)、まとめて戻すなら unmockkAll() を @AfterEach で呼びます。

object と companion object の違いは、関連記事「Kotlin companion object|static相当とobject」で扱っています。拡張関数のしくみは、関連記事「Kotlin拡張関数の使い方|拡張プロパティとメンバ関数優先の注意点」で扱っています。

every の答え方:returns・answers・throws・justRun

every { repo.findById(1) } returns User(1, "Ito", "ito@example.com")
every { repo.findById(2) } returns null
every { repo.findById(3) } throws IllegalStateException("DB down")
every { repo.save(any()) } answers { firstArg() }      // 渡された User をそのまま返す
every { repo.findById(4) } returnsMany listOf(null, User(4, "Sato", "s@example.com"))
justRun { mail.send(any(), any()) }
答え方 意味
returns value その値を返す
returnsMany list 呼ばれるたびに次の要素を返す(最後の値はそのまま続く)
returnsArgument(n) n 番目の引数を返す
throws ex 例外を投げる
throwsMany list 呼ばれるたびに次の例外を投げる
answers { … } ブロックの結果を返す。firstArg()・secondArg()・arg(n)・args が使える
coAnswers { … } suspend のブロックで答える
just Runs・justRun { … } Unit を返す(何もしない)
just Awaits 戻らない(suspend 関数用。1.13.3 から)
answers { callOriginal() } 本物の処理を呼ぶ

続けて違う答えを返すときは andThen でつなぎます。

every { repo.findById(5) } returns null andThen User(5, "Ito", "i@example.com")
every { mail.send(any(), any()) } throws RuntimeException("1回目は失敗") andThenJust Runs
続きの答え方 意味
andThen value 次はこの値
andThenMany list 次からはリストの値を順に
andThenThrows ex 次は例外
andThen { … } 次はブロックの結果
andThenJust Runs 次は Unit(1.12.2 から)

同じ呼び出しに一致する every が2つあると、後に書いたほうが使われます。 ソースでも、一致する設定のうち最後のもの(findLast)を選んでいます。 引数が具体的なもの(findById(1))と any() を両方書くときは、any() を先に書きます。ドキュメントの部分モックの例も、every { adder.addOne(any()) } returns -1 の後に every { adder.addOne(3) } answers { callOriginal() } を書いています。

引数マッチャー

引数にそのまま値を書くと eq()(等しいか)で比べます。

マッチャー 意味
any() 何でも(型は合わせる)
allAny() その呼び出しの引数を全部 any() 扱い
eq(v)・neq(v) 等しい・等しくない
refEq(v) 同じインスタンス
match { it.startsWith("a") } 条件に合う
isNull()・isNull(inverse = true) null・null でない
ofType(T::class) その型
more(v)・less(v)・range(a, b) 大小の比較(compareTo)
and(a, b)・or(a, b)・not(m) 組み合わせ
capture(slot)・capture(list) 引数を取り出す(後述)
withArg { … } verify の中だけ。引数を受け取ってアサーションを書く
every { repo.save(match { it.email.endsWith("@example.com") }) } answers { firstArg() }
verify { mail.send(eq("ito@example.com"), match { "Ito" in it }) }

verify:回数・順序・confirmVerified

verify { repo.save(any()) }                       // 1回以上
verify(exactly = 1) { repo.save(any()) }          // ちょうど1回
verify(exactly = 0) { mail.send(any(), any()) }   // 呼ばれていない
verify(atLeast = 2, atMost = 3) { repo.findById(any()) }
verify(timeout = 3000) { mail.send(any(), any()) } // 別スレッドの呼び出しを最大3秒待つ
verify { mail wasNot Called }                     // このモックは何も呼ばれていない
書き方 確かめること
verify { … } 書いた呼び出しがあった(順序は問わない)
verify(exactly = n)・atLeast・atMost 回数
verify(inverse = true) { … } 呼ばれていない
verifyOrder { a; b } a の後に b(間に他の呼び出しがあってもよい)
verifySequence { a; b } そのモックへの呼び出しが a, b だけで、この順
verifyAll { a; b } そのモックへの呼び出しが a, b だけ(順序は問わない)
verify { m wasNot Called } モックが一度も呼ばれていない
confirmVerified(m) m への呼び出しを、すべて verify 済みか
checkUnnecessaryStub(m) 書いた every が、すべて使われたか
excludeRecords { … } その呼び出しを記録から外す(confirmVerified の対象外にする)
verifyOrder {
    repo.save(any())
    mail.send(any(), any())
}
confirmVerified(mail)   // mail への呼び出しは全部 verify 済み

confirmVerified は、Mockito の verifyNoMoreInteractions に当たります。 「確かめていない呼び出しが残っていない」ことを保証します。ドキュメントでは、verifySequence・verifyAll はもともと全部の呼び出しを確かめるので、それと一緒に使う意味は薄いとされています。1.14.6 からは confirmVerified(m, clear = true) で、確かめた後に記録を消せます。

回数の指定は、verifyCount { 1 * { … } } という書き方もあります。

slot・capture:渡された引数を取り出す

val saved = slot<User>()
every { repo.save(capture(saved)) } answers { firstArg() }

service.register("Ito", "ito@example.com")

assertEquals("Ito", saved.captured.name)
書き方 取り出せるもの
slot<T>() + capture(slot) 最後に渡された1つ(slot.captured)
slot<T?>() + captureNullable(slot) null も含めて最後の1つ
mutableListOf<T>() + capture(list) 渡された全部(呼ばれた順)
verify { m.f(withArg { assertEquals(…, it) }) } 取り出さずに、その場で確かめる

複数回呼ばれる関数の引数を全部見たいときは、slot ではなく mutableListOf を使います。 ソースを見ると、slot で捕まえた呼び出しを verify で2回以上一致させると、次のエラーで止まるようになっています。

… execution is being verified more than once and its arguments are being captured with a slot.
This will store only the argument of the last invocation in the slot.
If you want to store all the arguments, use a mutableList to capture arguments.

まだ何も捕まえていない slot の captured を読むと、IllegalStateException: Value not yet captured. になります(ソースの文言)。slot.isCaptured で先に確かめられます。

コルーチン:coEvery・coVerify

suspend 関数には every ではなく coEvery、verify ではなく coVerify を使います。 上の javap で見た通り、suspend 関数は Java のメソッドとしては Continuation という引数が1つ多い形になっていて、普通の関数とは呼び出し方が違うためです。

@Test
fun `ニックネームが空なら名無し`() = runTest {
    coEvery { api.fetchNickname(1) } returns ""

    assertEquals("名無し", service.nickname(1))

    coVerify(exactly = 1) { api.fetchNickname(1) }
}
普通の関数 suspend 関数
every coEvery
verify coVerify
answers { … } coAnswers { … }(中で delay などを呼べる)
justRun coJustRun
verifyOrder・verifySequence・verifyAll coVerifyOrder・coVerifySequence・coVerifyAll
match { … } coMatch { … }
— coJustAwait { … }(ずっと戻らない)
coEvery { api.fetchNickname(any()) } coAnswers {
    delay(1_000)          // runTest の中では仮想時間なので待たない
    "Ito"
}

コルーチンの基本は、関連記事「Kotlinコルーチン入門|launch・async・runBlocking」で扱っています。

アノテーションと JUnit 5 で書く完成コード

import io.mockk.every
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.confirmVerified
import io.mockk.impl.annotations.InjectMockKs
import io.mockk.impl.annotations.MockK
import io.mockk.junit5.MockKExtension
import io.mockk.mockkObject
import io.mockk.slot
import io.mockk.unmockkObject
import io.mockk.verify
import io.mockk.verifyOrder
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith

@ExtendWith(MockKExtension::class)
class UserServiceTest {

    @MockK
    lateinit var repo: UserRepository

    @MockK(relaxUnitFun = true)
    lateinit var mail: MailSender

    @MockK
    lateinit var api: ProfileApi

    @InjectMockKs
    lateinit var service: UserService

    @AfterEach
    fun tearDown() {
        unmockkObject(IdGenerator)
    }

    @Test
    fun `登録するとIDを振って保存しメールを送る`() {
        mockkObject(IdGenerator)
        every { IdGenerator.next() } returns 100L
        val saved = slot<User>()
        every { repo.save(capture(saved)) } answers { firstArg() }

        val user = service.register("Ito", "ito@example.com")

        assertEquals(User(100, "Ito", "ito@example.com"), user)
        assertEquals(100L, saved.captured.id)
        verifyOrder {
            repo.save(any())
            mail.send("ito@example.com", match { "Ito" in it })
        }
        confirmVerified(mail)
    }

    @Test
    fun `名前を変えると新しい名前で保存する`() {
        every { repo.findById(1) } returns User(1, "Ito", "ito@example.com")
        every { repo.save(any()) } answers { firstArg() }

        val user = service.rename(1, "Sato")

        assertEquals("Sato", user.name)
        verify { repo.save(withArg { assertEquals("Sato", it.name) }) }
    }

    @Test
    fun `無いIDならNoSuchElementException`() {
        every { repo.findById(99) } returns null

        assertFailsWith<NoSuchElementException> { service.rename(99, "Sato") }
        verify(exactly = 0) { repo.save(any()) }
    }

    @Test
    fun `ニックネームが空なら名無し`() = runTest {
        coEvery { api.fetchNickname(1) } returns ""

        assertEquals("名無し", service.nickname(1))
        coVerify(exactly = 1) { api.fetchNickname(1) }
    }
}
注釈・クラス 意味
@ExtendWith(MockKExtension::class) JUnit 5 で注釈のモックを初期化する
@MockK mockk() と同じ。relaxed・relaxUnitFun も指定できる
@RelaxedMockK mockk(relaxed = true) と同じ
@SpyK spyk() と同じ
@InjectMockKs モックをコンストラクタなどに入れて、テスト対象を作る
MockKAnnotations.init(this) JUnit 4 などで、注釈のモックを自分で初期化する

@InjectMockKs は、ドキュメントによると、名前で探してから型で探して注入します。既定では lateinit var か、値の入っていない var だけが対象です。

ドキュメントでは、MockKExtension はクラスのテストが全部終わったとき(@AfterAll)に unmockkAll と clearAllMocks を呼びます。テストごとに戻したい object・static のモックは、上のように @AfterEach で戻します。 次の注釈をクラスに付けると、毎テスト後の確認も自動になります。

注釈 テストごとに自動で呼ぶもの
@MockKExtension.ConfirmVerification confirmVerified(全モック)
@MockKExtension.CheckUnnecessaryStub checkUnnecessaryStub(全モック)
@MockKExtension.KeepMocks 最後の unmockkAll・clearAllMocks を止める

JUnit の書き方は、関連記事「JUnitの使い方|単体テストの書き方と観点【JUnit 5・6】」で扱っています。

Mockito との対応表

やりたいこと Mockito MockK
モックを作る mock(Repo::class.java) mockk<Repo>()
戻り値を決める `when`(repo.findById(1)).thenReturn(u) every { repo.findById(1) } returns u
例外を投げる thenThrow(E()) throws E()
順に違う値 thenReturn(a, b) returnsMany listOf(a, b)・andThen
引数から答える thenAnswer { it.getArgument<User>(0) } answers { firstArg() }
戻り値なし doNothing().when(mail).send(…) justRun { mail.send(any(), any()) }
何でも一致 any() any()
呼ばれたか verify(repo).save(u) verify { repo.save(u) }
回数 verify(repo, times(2)) verify(exactly = 2)
呼ばれていない verify(repo, never()) verify(exactly = 0)・wasNot Called
他の呼び出しが無い verifyNoMoreInteractions(repo) confirmVerified(repo)
順序 inOrder(a, b).verify(…) verifyOrder { … }
引数を取り出す ArgumentCaptor slot()+capture()
スパイ spy(obj) spyk(obj)
static mockStatic(X::class.java) mockkStatic(…)
Kotlin の object — mockkObject(Obj)
suspend 関数 — coEvery・coVerify
設定していない呼び出し null・0・空などを返す 例外(relaxed にすると値を返す)
JUnit 5 の注釈 @Mock・@InjectMocks @MockK・@InjectMockKs
Spring のテスト @MockitoBean @MockkBean(SpringMockK)

Java で Mockito を使う書き方は、関連記事「Mockitoの使い方|JUnit 5での基本からよくあるエラーまで」で扱っています。

Kotlin から Mockito をそのまま使うと何が起きるか(kotlinc で再現)

Mockito の新しい版(5 以降)は、既定のモック作成方式(inline mock maker)で final クラスもモックにできます。それでも、Kotlin から使うと次の2つで引っかかります。

① when が Kotlin の予約語

Mockito の when と同じ名前の static メソッドを持つクラスを作り、Kotlin から呼びました。

W1.kt:2:14: error: classifier 'class Mockito : Any' does not have a companion object, so it cannot be used as an expression.
W1.kt:2:22: error: the expression cannot be a selector (cannot occur after a dot).

Mockito.`when`(…) とバッククォートで囲むと通りました。

② any() が null を返し、Kotlin の非 null の引数で落ちる

Mockito の any() は、マッチャーを登録して null を返すしくみです。同じく null を返すだけの any() を Java で作り、fun findByName(name: String)(非 null の引数)に渡しました。

repo.findByName(ArgumentMatchers.any())
NPE: any(...) must not be null

Kotlin のコンパイラが「Java から来た値が null でないか」の確認を差し込むため、モックに届く前に NullPointerException になりました。 MockK の any() は Kotlin で書かれていて、この問題が起きません。Mockito を使い続ける場合は、mockito-kotlin(Mockito を Kotlin から使うための補助ライブラリ)の関数を使う方法があります。

よくあるエラーと原因

エラー文は MockK 1.14.11 のソースにある文字列です。

エラー文(先頭) 原因 直し方
MockKException: no answer found for … every を書いていない呼び出しが、厳格なモックに来た。引数が every と違う場合も同じ every を足す・引数を any() にする・relaxUnitFun
Missing mocked calls inside every { ... } block: make sure the object inside the block is a mock every { } の中にモックの呼び出しが無い。本物のオブジェクトや inline 関数を書いた モックを渡しているか確かめる。inline 関数は中の依存をモックにする
Missing calls inside verify { ... } block. verify { } の中にモックの呼び出しが無い 同上
Bad recording sequence. Please finalize every { ... } block with returns/answers/just Runs every { … } の後に returns などを書き忘れた returns・answers・just Runs を書く
AssertionError: Verification failed: call 1 of 1: … was not called verify した呼び出しが無かった 呼び出し側か、verify の引数を見直す
… One matching call found, but needs exactly 2 calls 回数が違う exactly の数を見直す
… Only one matching call to … happened, but arguments are not matching: 呼ばれたが引数が違う 続く差分を見て引数を直す
calls are not in verification order verifyOrder の順序と違う 呼び出し順を見直す
AssertionError: Verification acknowledgment failed confirmVerified で、verify していない呼び出しが残っていた 続く Not verified calls: を verify するか、excludeRecords
IllegalStateException: Value not yet captured. 捕まえる前の slot を読んだ 呼び出しが起きたか、slot.isCaptured で確かめる
ClassCastException(relaxed のモックで) ジェネリクスの戻り値を relaxed で返そうとした その関数だけ every を書く

一番多い no answer found の読み方です。ソースでは、メッセージは次の形で組み立てられています。

no answer found for <モックの型>(#番号).<関数名>(<実際の引数>) among the configured answers: (<設定済みの every>)

among the configured answers の後ろに、書いた every の一覧が出ます。「実際の引数」と「設定済みの every」を見比べると、どこが違うかが分かります。 たとえば every { repo.findById(1) } だけを書いて findById(2) が呼ばれた、every { repo.save(user) } の user と実際の引数が equals で等しくない、などです。

JDK 16 以降で、スパイや mockkStatic に InaccessibleObjectException・IllegalAccessException が出ることがある、という既知の問題もドキュメントに挙がっています。

よくある質問

Q. clearAllMocks と unmockkAll の違いは? A. ドキュメントでは、clear は「モックの内部の状態(設定と記録)を消して空にする」、unmock は「モックにするために変えたクラスを元に戻す」です。clearAllMocks は通常・object・static・コンストラクタのモックをすべてクリアし、unmockkAll は object・static・コンストラクタのモックを元に戻します。mockkObject したものを本物に戻すのは unmockk… のほうです。

Q. private 関数はモックにできますか。 A. ドキュメントの「Private functions mocking / dynamic calls」の節では、spyk<Car>(recordPrivateCalls = true) で作ったスパイに、every { mock["accelerate"]() } returns … の形で書いています。ただ、private 関数をモックにしたくなるのは、クラスを分けたほうがよい合図のことも多くあります。

Q. inline 関数はモックにできますか。 A. できません。ドキュメントとエラー文にある通り、inline 関数は呼び出し元に展開されるため、呼び出しが記録されません。中で使っている依存をモックにします。

Q. data class の引数はどう比べられますか。 A. 引数にそのまま値を書くと eq() で比べ、equals が使われます。data class は中身で equals するので、同じ中身なら一致します。data class の equals は、関連記事「Kotlin data classの使い方|copy・equalsとclass差」で扱っています。

まとめ

  • 基本は every { } returns と verify { }。モックは既定で厳格で、書いていない呼び出しは no answer found
  • 副作用だけの依存は relaxUnitFun = true、全部ゆるくするなら relaxed = true
  • object は mockkObject、トップレベル関数は mockkStatic。Java では static になっていることを javap で確認した
  • suspend 関数は coEvery・coVerify。Java のメソッドでは Continuation 引数が増えている
  • 引数は slot(最後の1つ)・mutableListOf(全部)・withArg
  • Mockito を Kotlin から使うと、when が予約語で、any() が any(...) must not be null の NullPointerException になった

参考・出典

確認日はいずれも 2026年10月12日です。

  • MockK 公式ドキュメント:https://mockk.io/
  • MockK(GitHub、README とソース・タグ v1.14.11):https://github.com/mockk/mockk
  • MockK リリース一覧:https://github.com/mockk/mockk/releases
  • SpringMockK(GitHub):https://github.com/Ninja-Squad/springmockk
  • Spring Boot ドキュメント「Kotlin Support」(Testing):https://docs.spring.io/spring-boot/reference/features/kotlin.html
  • Mockito 5.0.0 リリースノート:https://github.com/mockito/mockito/releases/tag/v5.0.0
  • mockito-kotlin(GitHub):https://github.com/mockito/mockito-kotlin

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「MockK 使い方|every・verify・coEveryとMockito対応表」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?