0Pricing
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.

Mocking with Mockito is a free Android Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Android Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

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.

Frequently asked questions

Is the “Mocking with Mockito” lesson free?

Yes — the full text of “Mocking with Mockito” is free to read here on the web, and the Android Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Android Academy course, upgrade to CoddyKit PRO.

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; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.

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