Android
Android

Pengujian unit (unit testing) adalah bagian penting dalam pengembangan aplikasi Android. Dengan unit test, Anda dapat memastikan bahwa setiap komponen aplikasi berfungsi sebagaimana mestinya sebelum diintegrasikan. Salah satu library yang populer untuk mocking dalam pengujian unit di Kotlin adalah MockK. MockK memungkinkan Anda membuat objek mock dengan mudah dan ekspresif, sehingga memudahkan pengujian unit.

Pada artikel ini, kita akan membahas cara mengimplementasikan unit test menggunakan MockK di aplikasi Android dengan Kotlin. Kita akan mencakup setup, pembuatan mock, dan contoh pengujian unit untuk sebuah kelas sederhana.

Apa itu MockK?

MockK adalah library mocking yang dirancang khusus untuk Kotlin. Dibandingkan dengan library mocking lain seperti Mockito, MockK menawarkan sintaksis yang lebih alami untuk Kotlin dan mendukung fitur-fitur Kotlin seperti suspending functions, coroutines, dan extension functions.

Keuntungan Menggunakan MockK

  1. Sintaksis yang Ekspresif: MockK menggunakan DSL (Domain Specific Language) yang mudah dipahami.
  2. Dukungan untuk Fitur Kotlin: MockK mendukung coroutines, suspending functions, dan extension functions.
  3. Fleksibilitas: MockK memungkinkan mocking objek, static methods, dan bahkan objek yang sulit dimock seperti final class.

Langkah Implementasi Unit Test dengan MockK

Mari kita lihat langkah-langkah untuk mengimplementasikan unit test menggunakan MockK di aplikasi Android.

1. Tambahkan Dependensi MockK

Pertama, tambahkan dependensi MockK ke file build.gradle level modul:

dependencies {
    testImplementation "io.mockk:mockk:1.13.7"
    testImplementation "junit:junit:4.13.2"
    testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4" // Jika menggunakan coroutines
}

Setelah menambahkan dependensi, sync project Anda.

2. Buat Kelas yang Akan Diuji

Sebagai contoh, kita akan membuat kelas UserRepository yang bertanggung jawab untuk mengambil data pengguna dari UserService.

class UserRepository(private val userService: UserService) {

    suspend fun getUser(id: Int): User {
        return userService.getUser(id)
    }
}

interface UserService {
    suspend fun getUser(id: Int): User
}

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

3. Buat Unit Test dengan MockK

Buat file test di direktori src/test dan tulis pengujian unit untuk UserRepository. Kita akan menggunakan MockK untuk membuat mock dari UserService.

import io.mockk.coEvery
import io.mockk.mockk
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals
import org.junit.Test

class UserRepositoryTest {

    @Test
    fun `getUser should return user from service`() = runBlocking {
        // 1. Buat mock dari UserService
        val userService = mockk<UserService>()

        // 2. Definisikan perilaku mock
        coEvery { userService.getUser(1) } returns User(1, "John Doe", "johndoe@example.com")

        // 3. Inisialisasi UserRepository dengan mock UserService
        val userRepository = UserRepository(userService)

        // 4. Panggil metode yang akan diuji
        val result = userRepository.getUser(1)

        // 5. Verifikasi hasil
        assertEquals("John Doe", result.name)
        assertEquals("johndoe@example.com", result.email)
    }
}

Penjelasan Kode:

  1. Membuat Mockmockk<UserService>() digunakan untuk membuat mock dari UserService.
  2. Mendefinisikan Perilaku MockcoEvery { userService.getUser(1) } digunakan untuk mendefinisikan perilaku mock ketika metode getUser dipanggil dengan parameter 1.
  3. Menginisialisasi RepositoryUserRepository(userService) diinisialisasi dengan mock UserService.
  4. Memanggil Metode yang DiujiuserRepository.getUser(1) memanggil metode yang akan diuji.
  5. Verifikasi HasilassertEquals digunakan untuk memverifikasi bahwa hasil yang dikembalikan sesuai dengan yang diharapkan.

4. Menggunakan verify untuk Memastikan Metode Dipanggil

Selain mendefinisikan perilaku mock, Anda juga dapat memverifikasi bahwa metode tertentu telah dipanggil dengan menggunakan coVerify.

import io.mockk.coVerify
import io.mockk.mockk
import kotlinx.coroutines.runBlocking
import org.junit.Test

class UserRepositoryTest {

    @Test
    fun `getUser should call service`() = runBlocking {
        // 1. Buat mock dari UserService
        val userService = mockk<UserService>(relaxed = true)

        // 2. Inisialisasi UserRepository dengan mock UserService
        val userRepository = UserRepository(userService)

        // 3. Panggil metode yang akan diuji
        userRepository.getUser(1)

        // 4. Verifikasi bahwa metode getUser dipanggil
        coVerify { userService.getUser(1) }
    }
}

Penjelasan:

  • relaxed = true digunakan untuk membuat mock yang tidak memerlukan definisi perilaku eksplisit.
  • coVerify { userService.getUser(1) } memverifikasi bahwa metode getUser telah dipanggil dengan parameter 1.

5. Menggunakan slot untuk Menangkap Argumen

Jika Anda perlu menangkap argumen yang diteruskan ke metode mock, Anda bisa menggunakan slot.

import io.mockk.coEvery
import io.mockk.mockk
import io.mockk.slot
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals
import org.junit.Test

class UserRepositoryTest {

    @Test
    fun `getUser should capture argument`() = runBlocking {
        // 1. Buat mock dari UserService
        val userService = mockk<UserService>()

        // 2. Buat slot untuk menangkap argumen
        val idSlot = slot<Int>()

        // 3. Definisikan perilaku mock dan tangkap argumen
        coEvery { userService.getUser(capture(idSlot)) } returns User(1, "John Doe", "johndoe@example.com")

        // 4. Inisialisasi UserRepository dengan mock UserService
        val userRepository = UserRepository(userService)

        // 5. Panggil metode yang akan diuji
        userRepository.getUser(1)

        // 6. Verifikasi argumen yang ditangkap
        assertEquals(1, idSlot.captured)
    }
}

Penjelasan:

  • slot<Int>() digunakan untuk menangkap argumen bertipe Int.
  • capture(idSlot) menangkap argumen yang diteruskan ke metode getUser.

Kesimpulan

MockK adalah library mocking yang sangat powerful untuk pengujian unit di Kotlin. Dengan sintaksis yang ekspresif dan dukungan untuk fitur-fitur Kotlin seperti coroutines, MockK memudahkan Anda untuk menulis pengujian unit yang bersih dan mudah dipahami.

Dalam artikel ini, kita telah membahas cara mengimplementasikan unit test menggunakan MockK di aplikasi Android dengan Kotlin. Mulai dari setup, pembuatan mock, hingga verifikasi perilaku dan argumen, MockK menyediakan semua alat yang Anda butuhkan untuk pengujian unit yang efektif.

Dengan menguasai MockK, Anda dapat meningkatkan kualitas kode dan memastikan bahwa aplikasi Android Anda berfungsi dengan baik. Selamat mencoba!