Mocking dengan Mockito
Pisahkan dependency dengan Mockito dan MockK. Atur nilai pengembalian, verifikasi interaksi, tangkap argumen, dan gunakan spy untuk mocking sebagian.
Mocking dengan Mockito adalah pelajaran Android Academy gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Android Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Android Academy mencakup 4 pelajaran total.
Apa Itu Mocking?
Mock adalah objek tiruan yang menggantikan dependensi nyata dalam pengujian. Berbeda dari Fake (implementasi dalam memori yang berfungsi), Mock:
- Dibuat secara otomatis oleh pustaka
- Mencatat metode mana yang dipanggil dan dengan argumen apa
- Mengembalikan apa pun yang Anda minta untuk dikembalikan (stubbing)
- Memungkinkan Anda memverifikasi interaksi setelah pengujian
Penyiapan Mockito
Tambahkan Mockito dan MockK (alternatif yang mengutamakan Kotlin) ke 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'Membuat Mock
Buat Mock dengan mock() atau anotasi @Mock:
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 — Menentukan Nilai Kembalian
Gunakan whenever(mock.method()).thenReturn(value) untuk menetapkan nilai yang dikembalikan Mock:
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 callverify() — Memeriksa Interaksi
Gunakan verify() untuk memastikan bahwa suatu metode dipanggil — dan berapa kali:
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 menangkap argumen yang diteruskan ke metode Mock sehingga Anda dapat memastikan nilainya:
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 — Mocking yang Mengutamakan Kotlin
MockK dirancang untuk Kotlin dan secara alami menangani fungsi ekstensi, coroutine, dan objek:
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 Coroutine dengan MockK
Gunakan coEvery dan coVerify untuk fungsi suspend:
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 — Mocking Sebagian
spy membungkus objek nyata. Metode nyata dipanggil secara default, kecuali ditimpa:
// 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"Kapan Menggunakan Mock vs Fake
Panduan praktis:
- Gunakan Fake jika Anda memerlukan implementasi dalam memori yang berfungsi (DAO, repositori) — lebih mudah dibaca dan tidak memerlukan pustaka
- Gunakan Mock jika Anda perlu memverifikasi bahwa metode tertentu dipanggil dengan argumen tertentu (peristiwa analitik, panggilan API)
- Hindari penggunaan Mock berlebihan — jika Anda melakukan Mock pada semuanya, pengujian Anda memverifikasi Mock, bukan logika Anda
Kesalahan Umum
Hal-hal yang perlu dihindari saat melakukan Mocking:
- Melakukan Mock pada objek nilai — lakukan Mock pada interface/abstraksi, bukan kelas data
- Melakukan Mock terlalu dalam — jika Anda memerlukan 5 Mock dalam satu pengujian, kode tersebut terlalu erat keterkaitannya
- Tidak melakukan verifikasi saat interaksi penting — jangan hanya melakukan stub, tetapi lakukan verifikasi juga
- Default Kotlin + Mockito — parameter Kotlin secara default tidak boleh null; gunakan
mockito-kotlinatau MockK untuk menghindari kejutan akibat null
Mocking Objek & Objek Pendamping
MockK dapat melakukan Mock pada objek Kotlin dan objek pendamping — hal yang tidak mungkin dilakukan dengan 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)Pemeriksaan Cepat
Apa tujuan verify() dalam pengujian Mockito atau MockK?
Ringkasan: Mocking dengan Mockito & MockK
Mock memungkinkan Anda mengisolasi dan memverifikasi perilaku:
mock()/mockk()— membuat Mock dari interface atau kelaswhenever(...).thenReturn(...)/every { } returns ...— menetapkan nilai kembalian dengan stubcoEvery/coVerify— untuk fungsi suspend Kotlin (MockK)verify(mock).method(args)— memastikan metode dipanggilArgumentCaptor— menangkap dan memeriksa argumenspy()/spyk()— Mock sebagian dari objek nyata- Utamakan Fake untuk data; gunakan Mock untuk memverifikasi perilaku
Berikutnya: Pengujian UI dengan Espresso.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Mocking dengan Mockito” gratis?
Ya — teks lengkap “Mocking dengan Mockito” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Android Academy, upgrade ke CoddyKit PRO. Kursus Android Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Mocking dengan Mockito”?
Pisahkan dependency dengan Mockito dan MockK. Atur nilai pengembalian, verifikasi interaksi, tangkap argumen, dan gunakan spy untuk mocking sebagian. Kamu berlatih Android Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Android Academy?
Tidak diperlukan pengalaman sebelumnya. Android Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.
Berapa lama pelajaran “Mocking dengan Mockito” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Android Academy ini?
Ya. Setiap pelajaran Android Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Pengujian Unit dengan JUnit
- Mocking dengan Mockito
- Pengujian Antarmuka dengan Espresso
- Debugging & Pembuatan Profil