Test Doubles — apa itu, jenis dan penerapan

Penulis: IT Sectr Diterbitkan: 2026-04-10 Waktu membaca: 9 mnt

Test Doubles — adalah objek pengganti yang digunakan dalam pengujian unit sebagai pengganti ketergantungan nyata. Istilah ini diperkenalkan oleh Gerard Meszaros dalam buku “­xUnit Test Patterns” (2007) sebagai konsep umum untuk Mock, Stub, Fake, Spy dan Dummy. Menurut Martin Fowler (2024), Test Doubles memungkinkan isolasi komponen yang diuji dari lingkungannya, membuat pengujian menjadi deterministik, cepat, dan independen dari layanan eksternal.

Utama

  • Test Doubles — istilah umum untuk semua jenis objek pengganti dalam pengujian
  • Mock memeriksa interaksi: metode apa yang dipanggil dan dengan argumen apa
  • Stub mengembalikan nilai yang telah ditentukan tanpa memeriksa pemanggilan
  • Fake — implementasi kerja yang disederhanakan (misalnya, database in-memory)
  • Spy mencatat pemanggilan untuk verifikasi selanjutnya, Dummy mengisi parameter

Apa itu Test Doubles?

Test Doubles — adalah istilah dari industri otomotif (pemeran pengganti, “double” untuk aktor) yang dibawa ke pengembangan perangkat lunak. Seperti seorang pemeran pengganti menggantikan aktor dalam adegan berbahaya, Test Double menggantikan komponen nyata dalam skenario pengujian. Ini diperlukan ketika ketergantungan nyata tidak tersedia, lambat, non-deterministik, atau memiliki efek samping.

Konsep Test Double mencakup lima jenis spesifik, masing-masing menyelesaikan tugasnya sendiri. Tipologi Meszaros bersifat kanonik dan digunakan di semua panduan pengujian modern. Perbedaan antara jenis terletak pada tingkat kontrol dan verifikasi: dari pengisian parameter sederhana (Dummy) hingga pemeriksaan lengkap urutan pemanggilan (Mock).

Mengapa Test Doubles diperlukan

Tujuan utama Test Doubles adalah isolasi modul yang diuji. Dalam pengembangan mobile, ketergantungan nyata adalah server API, database, sistem file, sensor perangkat, layanan sistem (LocationManager, Camera, Bluetooth). Penggunaan langsung komponen-komponen ini membuat pengujian lambat, rapuh, dan tergantung pada lingkungan. Menurut Google Testing Blog (2023), pengujian unit yang terisolasi dengan baik dijalankan dalam milidetik, dan pengujian integrasi dalam hitungan detik dan menit.

Lima jenis Test Doubles

Klasifikasi Gerard Meszaros mencakup lima jenis Test Doubles, yang berbeda dalam perilaku dan tujuan penggunaan. Memahami perbedaan di antara mereka adalah dasar dari pengujian unit yang benar.

Dummy

Dummy — adalah objek yang diteruskan ke metode yang diuji, tetapi tidak pernah digunakan. Dummy hanya diperlukan untuk memenuhi tanda tangan metode. Di Kotlin, ini sering berupa null, emptyList() atau objek dengan pengganti. Dummy tidak boleh mengandung logika apa pun — jika dipanggil, pengujian harus gagal.

Fake

Fake — adalah implementasi yang disederhanakan namun berfungsi dari sebuah antarmuka. Tidak seperti Mock dan Stub, Fake berisi logika bisnis nyata, tetapi dalam bentuk yang disederhanakan. Contoh klasik — InMemoryUserRepository, yang menyimpan data di HashMap, bukan database. Fake digunakan ketika logika yang bergantung pada status perlu diuji, tetapi tanpa overhead infrastruktur nyata.

JenisTujuanContoh
DummyMengisi parameternull, objek kosong
FakeImplementasi kerja yang disederhanakanInMemoryRepository
StubMengembalikan nilai tetapwhen(api.getUser()).thenReturn(user)
SpyMencatat pemanggilan untuk pemeriksaanverify(spy).save(user)
MockMemeriksa interaksiverify(mock).sendEmail(email)

Stub

Stub mengembalikan nilai yang telah ditentukan untuk pemanggilan tertentu. Stub tidak memeriksa apakah ia dipanggil — ia hanya menyediakan data. Di Mockito, Stub dibuat melalui when(method).thenReturn(value). Stub ideal untuk pengujian ketika ketergantungan harus mengembalikan nilai tertentu, tetapi fakta pemanggilan itu sendiri tidak penting.

Spy

Spy — adalah pembungkus di sekitar objek nyata yang mencatat semua pemanggilan untuk verifikasi selanjutnya. Tidak seperti Mock, Spy mendelegasikan pemanggilan ke objek nyata, tetapi memungkinkan pemeriksaan bahwa pemanggilan tersebut terjadi. Di Mockito, Spy dibuat melalui spy(realObject). Spy berguna untuk mocking parsial ketika Anda ingin menggunakan objek nyata tetapi memeriksa beberapa pemanggilan.

Mock

Mock — adalah objek dengan ekspektasi pemanggilan yang telah ditentukan. Mock memeriksa apakah metode tertentu dipanggil dengan argumen tertentu dan dalam urutan tertentu. Tidak seperti Stub, Mock berfokus pada verifikasi perilaku, bukan pada pengembalian data. Mock adalah jenis Test Double yang paling kuat dan paling sering digunakan dalam pengembangan mobile.

Mock dan Stub: perbedaan utama

Perbedaan antara Mock dan Stub sering menyebabkan kebingungan bahkan di kalangan pengembang berpengalaman. Perbedaan utama terletak pada tujuan: Stub memeriksa status (state verification), Mock memeriksa perilaku (behavior verification).

Stub menjawab pertanyaan: “apakah kode mengembalikan hasil yang benar?”. Mock menjawab pertanyaan: “apakah kode memanggil metode yang benar dengan argumen yang benar?”. Dalam pengembangan mobile, Stub digunakan ketika hasilnya penting (misalnya, data dari repositori), dan Mock ketika efek sampingnya penting (misalnya, mengirim email, menulis ke database).

kotlin
// Stub: pemeriksaan status
every { repository.getUsers() } returns listOf(user)
val result = useCase.getUsers()
assertEquals(1, result.size)

// Mock: pemeriksaan perilaku
every { analytics.logEvent("purchase") } returns Unit
useCase.purchase(item)
verify { analytics.logEvent("purchase") }

Contoh Test Doubles di Kotlin

Contoh praktis dari semua lima jenis Test Doubles di Kotlin menggunakan MockK — pustaka mocking paling populer untuk proyek Android.

Fake: InMemoryUserRepository

kotlin
class InMemoryUserRepository : UserRepository {
    private val store = mutableMapOf<String, User>()

    override fun save(user: User) {
        store[user.email] = user
    }

    override fun findByEmail(email: String): User? {
        return store[email]
    }
}

Stub + Mock: tes UseCase

kotlin
class RegisterUseCaseTest {
    private val api = mockk<AuthApi>()
    private val repo = spyk(InMemoryUserRepository())
    private val useCase = RegisterUseCase(api, repo)

    fun `register user successfully`() = runTest {
        // Stub: mengembalikan respons API tetap
        coEvery { api.register("test@test.com") } returns AuthResult.Success("token123")

        val result = useCase.execute("test@test.com")

        // Verify: memeriksa bahwa pengguna telah disimpan
        verify { repo.save(any()) }
        assertTrue(result.isSuccess())
    }
}

Dummy: tes dengan parameter yang tidak digunakan

kotlin
data class Logger(val appContext: Context, val format: FormatType)

fun `test logger with dummy context`() {
    // Dummy: Context tidak digunakan di dalam Logger
    val dummyContext = mockk<Context>()
    val logger = Logger(dummyContext, FormatType.JSON)
    assertEquals(FormatType.JSON, logger.format)
}

Kapan menggunakan tiap jenis dalam pengembangan mobile

Pemilihan jenis Test Double tergantung pada apa yang tepat diuji: status, perilaku, atau integrasi. Dalam pengembangan mobile di Android dan iOS, rekomendasi berikut telah terbentuk.

Untuk ViewModel dan UseCase

Saat menguji ViewModel, gunakan Mock untuk ketergantungan yang menghasilkan efek samping (repositori, analytics, navigasi) dan Stub untuk ketergantungan yang mengembalikan data (klien API, ContentProvider). Ini memungkinkan pemeriksaan bahwa ViewModel menangani skenario sukses dan error dengan benar.

Untuk Repository dan Lapisan Data

Di tingkat Repository, Fake (implementasi database in-memory) dan Stub (respons API tetap) lebih disukai. Fake memungkinkan pengujian logika caching dan mode offline tanpa konfigurasi SQLite. Stub mensimulasikan berbagai kode HTTP: 200, 404, 500, timeout.

  • Pengujian unit logika bisnis — Mock untuk semua ketergantungan eksternal, Dummy untuk parameter yang tidak digunakan
  • Pengujian integrasi — Fake sebagai ganti Mock (memeriksa bahwa komponen bekerja bersama)
  • Pengujian UI — Stub untuk respons API (melalui MockWebServer atau WireMock)
  • Pengujian caching — Fake untuk database (in-memory sebagai ganti Room/SQLite)
  • Pengujian asinkron — Mock dengan dukungan coroutine (MockK + Turbine untuk Flow)

Kesalahan umum dalam penggunaan pengganti

Penggunaan Test Doubles yang tidak tepat — salah satu penyebab paling umum dari pengujian rapuh yang rusak pada setiap refactoring.

Over-mocking: penggunaan Mock yang berlebihan

Kesalahan paling umum — melakukan mocking pada segalanya. Jika setiap ketergantungan dalam pengujian digantikan oleh Mock, pengujian berhenti memeriksa perilaku nyata. Mock harus hanya untuk ketergantungan eksternal (jaringan, database, sistem file, layanan sistem). Komponen internal aplikasi (Value Object, data class, utilitas sederhana) tidak boleh diganti.

Under-specification: spesifikasi yang tidak memadai

Kesalahan kedua — membuat Mock tanpa menentukan ekspektasi. Jika metode dipanggil tanpa every / when, Mock mengembalikan nilai default (null, 0, false). Ini dapat menyebabkan pengujian positif palsu ketika Mock diam-diam mengembalikan null, dan pengujian menafsirkannya sebagai perilaku yang benar.

Over-verification: verifikasi berlebihan

Kesalahan ketiga — memeriksa setiap pemanggilan setiap Mock. Verify harus digunakan hanya untuk pemanggilan yang kritis dari sudut pandang logika bisnis. Verifikasi berlebihan membuat pengujian rapuh: perubahan urutan pemanggilan dalam kode produksi merusak pengujian tanpa mengubah perilaku.

Pertanyaan yang Sering Diajukan

Apa perbedaan antara Mock dan Stub?

Stub mengembalikan data dan memeriksa status (apa yang dikembalikan), sedangkan Mock memeriksa perilaku (metode apa yang dipanggil). Stub = “kembalikan X”, Mock = “periksa bahwa Y dipanggil dengan argumen Z”. Dalam pengujian nyata, satu objek sering bertindak sebagai Stub dan Mock secara bersamaan.

Kapan menggunakan Fake sebagai ganti Mock?

Fake lebih diutamakan daripada Mock ketika menguji logika yang bergantung pada status: caching, mode offline, transaksi. Fake (implementasi in-memory) memungkinkan pengujian skenario ini tanpa pemanggilan verify yang rapuh. Mock lebih cocok untuk memeriksa pengiriman data: analytics, notifikasi push, email.

Pustaka Test Doubles mana yang lebih baik untuk Android?

Untuk proyek Android di Kotlin, MockK direkomendasikan. Ia mendukung coroutine, fungsi suspend, sealed class dan fungsi extension tanpa konfigurasi tambahan. Untuk proyek Java, standarnya masih Mockito — pustaka paling populer dengan dokumentasi yang luas.

Bagaimana cara menguji Kotlin Flow dengan Test Doubles?

Untuk menguji Kotlin Flow, gunakan pustaka Turbine bersama dengan MockK. Turbine menyederhanakan pemeriksaan emisi Flow: Anda dapat memeriksa urutan nilai, penyelesaian aliran, dan pengecualian. Stub untuk Flow mengembalikan flowOf(value), Mock memeriksa apakah Flow telah dikumpulkan.

Apakah diperbolehkan menggunakan Test Doubles dalam pengujian UI?

Ya, tetapi pada tingkat respons API, bukan komponen UI. Pustaka MockWebServer (OkHttp) dan WireMock memungkinkan penggantian respons HTTP dalam pengujian UI. Komponen UI itu sendiri (Compose, SwiftUI Views) tidak boleh diganti — perilakunya diuji melalui pengujian screenshot dan Espresso.

Kesimpulan

  • Test Doubles — istilah umum untuk lima jenis objek pengganti: Mock, Stub, Fake, Spy, Dummy
  • Mock memeriksa perilaku (verify), Stub mengembalikan data (thenReturn), Fake — bekerja seperti implementasi nyata yang disederhanakan
  • Spy membungkus objek nyata dan mencatat pemanggilan, Dummy mengisi parameter yang tidak digunakan
  • Tipologi Gerard Meszaros — klasifikasi kanonik yang digunakan di semua framework mocking modern
  • Untuk proyek Kotlin direkomendasikan MockK, untuk Java — Mockito, untuk iOS — Cuckoo atau OHHTTPStubs
  • Kesalahan umum: over-mocking (mengganti segalanya), under-specification (ekspektasi tidak terdefinisi), over-verification (verifikasi berlebihan)
  • Fake lebih diutamakan daripada Mock saat menguji logika dengan status — caching, mode offline, dan transaksi

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga