Android Academy · Lesson

Mocking with Mockito

Isolate dependencies with Mockito and MockK. Stub return values, verify interactions, capture arguments, and use spies for partial mocking.

Lesson 2 of 414 steps

Mocking with Mockito is a free Android Academy lesson on CoddyKit. This is lesson 2 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the Android Academy learning path, and your progress syncs across the web and the CoddyKit app. The Android Academy course includes 4 lessons in total.

What Is Mocking?

A mock is a fake object that replaces a real dependency in tests. Unlike a Fake (a working in-memory implementation), a mock:

  • Is generated automatically by a library
  • Records which methods were called and with what arguments
  • Returns whatever you tell it to return (stubbing)
  • Lets you verify interactions after the test

Mockito Setup

Add Mockito and MockK (Kotlin-first alternative) to app/build.gradle:

// app/build.gradle:
testImplementation 'org.mockito:mockito-core:5.10.0'
testImplementation 'org.mockito.kotlin:mockito-kotlin:5.2.1'

// MockK (Kotlin-idiomatic alternative to Mockito):
testImplementation 'io.mockk:mockk:1.13.10'

Creating Mocks

Create mocks with mock() or the @Mock annotation:

import org.mockito.kotlin.*

interface UserApi {
    suspend fun fetchUsers(): List<User>
    suspend fun deleteUser(id: Int)
}

class RepositoryTest {

    // Option 1: create inline
    private val api: UserApi = mock()

    // Option 2: use annotation + MockitoJUnit4Runner
    @Mock lateinit var api2: UserApi

    @get:Rule
    val mockitoRule = MockitoJUnit.rule()
}

Stubbing — Defining Return Values

Use whenever(mock.method()).thenReturn(value) to set what a mock returns:

val api: UserApi = mock()

// Stub a return value:
whenever(api.fetchUsers()).thenReturn(
    listOf(User(1, "Alice"), User(2, "Bob"))
)

// Stub an exception:
whenever(api.fetchUsers()).thenThrow(RuntimeException("Network error"))

// Return different values on consecutive calls:
whenever(api.fetchUsers())
    .thenReturn(emptyList())           // first call
    .thenReturn(listOf(User(1, "Alice"))) // second call

verify() — Checking Interactions

Use verify() to assert that a method was called — and how many times:

val api: UserApi = mock()
val repo = UserRepository(api)

repo.refreshUsers()

// Verify that fetchUsers() was called exactly once:
verify(api).fetchUsers()

// Verify called with specific argument:
repo.deleteUser(42)
verify(api).deleteUser(42)

// Verify called exactly 3 times:
verify(api, times(3)).fetchUsers()

// Verify never called:
verify(api, never()).deleteUser(any())

ArgumentCaptor

ArgumentCaptor captures the argument passed to a mock method so you can assert its value:

val api: UserApi = mock()
val captor = argumentCaptor<User>()

val repo = UserRepository(api)
repo.saveUser(User(1, "Alice"))

verify(api).saveUser(captor.capture())

val captured = captor.firstValue
assertEquals(1, captured.id)
assertEquals("Alice", captured.name)

MockK — Kotlin-First Mocking

MockK is designed for Kotlin and handles extension functions, coroutines, and objects natively:

import io.mockk.*

val api = mockk<UserApi>()

// Stub:
every { api.fetchUsers() } returns listOf(User(1, "Alice"))

// Stub suspend function:
coEvery { api.fetchUsers() } returns listOf(User(1, "Alice"))

// Verify:
val repo = UserRepository(api)
runBlocking { repo.refresh() }
coVerify { api.fetchUsers() }

Mocking Coroutines with MockK

Use coEvery and coVerify for suspend functions:

val api = mockk<UserApi>()

// Stub suspend function:
coEvery { api.fetchUsers() } returns listOf(User(1, "Alice"))
coEvery { api.deleteUser(any()) } just Runs  // returns Unit

// Test:
runTest {
    val repo = UserRepository(api)
    repo.refresh()
    coVerify(exactly = 1) { api.fetchUsers() }
    coVerify(exactly = 0) { api.deleteUser(any()) }
}

Spy — Partial Mocking

A spy wraps a real object. Real methods are called by default unless overridden:

// Mockito Spy:
val realList = mutableListOf("a", "b", "c")
val spyList = spy(realList)

// Real method called:
spyList.add("d")
assertEquals(4, spyList.size)   // real add() was called

// Override specific method:
doReturn(99).`when`(spyList).size
assertEquals(99, spyList.size)  // overridden

// MockK Spy:
val spyObj = spyk(RealService())
every { spyObj.expensiveCall() } returns "fake result"

When to Use Mocks vs Fakes

Practical guidelines:

  • Use a Fake when you need a working in-memory implementation (DAO, repository) — easier to read, no library needed
  • Use a Mock when you need to verify that a specific method was called with specific arguments (analytics events, API calls)
  • Avoid over-mocking — if you mock everything, your tests verify the mocks, not your logic

Common Mistakes

Pitfalls to avoid with mocking:

  • Mocking value objects — mock interfaces/abstractions, not data classes
  • Mocking too deeply — if you need 5 mocks in one test, the code is too coupled
  • Not verifying when interaction matters — don't just stub, also verify
  • Mockito + Kotlin defaults — Kotlin params are non-null by default; use mockito-kotlin or MockK to avoid null surprises

Mocking Objects & Companion Objects

MockK can mock Kotlin objects and companion objects — impossible with Mockito:

object DateProvider {
    fun today(): String = "2024-01-01"
}

// In test:
mockkObject(DateProvider)
every { DateProvider.today() } returns "2099-12-31"

val result = DateProvider.today()
assertEquals("2099-12-31", result)

// Restore after test:
unmockkObject(DateProvider)

Quick Check

What is the purpose of verify() in a Mockito or MockK test?

Recap: Mocking with Mockito & MockK

Mocks let you isolate and verify behavior:

  • mock() / mockk() — create a mock from an interface or class
  • whenever(...).thenReturn(...) / every { } returns ... — stub return values
  • coEvery / coVerify — for Kotlin suspend functions (MockK)
  • verify(mock).method(args) — assert the method was called
  • ArgumentCaptor — capture and inspect arguments
  • spy() / spyk() — partial mock of a real object
  • Prefer Fakes for data; use Mocks to verify behavior

Next: UI testing with Espresso.

Free to start

Learn Kotlin with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
36
Lessons
152

Frequently Asked Questions

Is the “Mocking with Mockito” lesson free?

Yes — any 3 lessons of the Android Academy learning path, including “Mocking with Mockito”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The Android Academy course includes 4 lessons in total.

What will I learn in “Mocking with Mockito”?

Isolate dependencies with Mockito and MockK. Stub return values, verify interactions, capture arguments, and use spies for partial mocking. You practise Android Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Android Academy?

No prior experience is required. Android Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 2 of 4.

How long does the “Mocking with Mockito” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Android Academy lesson?

Yes. Every Android Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Unit Testing with JUnit
  2. Mocking with Mockito
  3. UI Testing with Espresso
  4. Debugging & Profiling
← Back to Android Academy