MockK: nedir, temel kavramlar ve sözdizimi

Yazar: IT Sectr Yayınlanma: 2026-04-08 Okuma süresi: 8 dk

MockK, mock nesneler oluşturmak için Kotlin-first bir framework'tür ve Kotlin ekosistemi için dil özellikleri (eşyordamlar, genişletme fonksiyonları, data class ve sealed class) dikkate alınarak özel olarak tasarlanmıştır. Java'dan Kotlin'e taşınan Mockito'nun aksine, MockK baştan itibaren Kotlin sözdizimi için tasarlanmıştır ve final sınıflarla çalışmak için ek eklenti gerektirmez. MockK.io'ya göre, kütüphane birim testi yapan Kotlin projelerinin %40'ından fazlasında kullanılmaktadır.

Önemli Noktalar

  • MockK — eşyordamlar ve dil özellikleri desteği ile Kotlin odaklı bir mock kütüphanesi.
  • mockk() — Mockito.mock()'a benzer şekilde mock nesne oluşturmanın ana yöntemi.
  • every { } — bildirimsel tarzda mock davranışını (stubbing) yapılandırmak için blok.
  • coEvery / coVerify — eşyordamların suspend fonksiyonlarıyla çalışmak için özel yapılar.
  • Relaxed mock — açık stubbing olmadan varsayılan değerleri döndüren bir mock.

MockK Nedir?

MockK, mock nesneler oluşturmak için Kotlin'de yazılmış ve sözdizimi için optimize edilmiş bir kütüphanedir. Mockito ile aynı sorunları çözer — test edilen kodu bağımlılıklardan ayırmak — ancak bunu Kotlin'e özgü yapıları kullanarak yapar: lambdalar, DSL, reified generics ve suspend fonksiyonları.

Taşınan çözümlere göre MockK'nın ana avantajı yerel Kotlin desteğidir. Mockito'da, bir final sınıfını mocklamak opt-in (mockito-inline) gerektirir ve statik yöntemler mockStatic gerektirir. MockK bunu varsayılan olarak destekler, çünkü Kotlin sınıfları varsayılan olarak finaldir ve bu sınırlamayı aşmak kütüphane mimarisine yerleşiktir.

1.13.12 sürümü (2024), Kotlin 2.0, K2 derleyicisi ve çoklu platform projelerini (KMP) destekleyen kararlı bir sürümdür. MockK ayrıca Kotlin/Native ve Kotlin/JS ile de çalışır ve bu, ne Mockito'nun ne de EasyMock'un uygulanamadığı KMP projeleri için onu tek seçenek haline getirir.

MockK, Kotlin'in özellikleri dikkate alınarak tasarlanmıştır ve performanstan ödün vermeden kısa ve type-safe bir API sağlamak için dil özelliklerini — reified generics, lambdalı DSL, inline fonksiyonlar — kullanır.

MockK Nasıl Çalışır

MockK'nın mekanizması, ByteBuddy kütüphanesi (Mockito gibi) aracılığıyla bayt kodu enstrümantasyonuna dayanır, ancak bunu Kotlin dostu bir DSL ile sarar. when().thenReturn() zincirleri yerine, MockK dilin doğal bir uzantısı gibi görünen lambda blokları every { } ve coEvery { } kullanır. Perde arkasında, MockK lambda içindeki çağrıyı yakalar, yansıma yoluyla yöntemi ve argümanları analiz eder ve kaydedilen stubbing kurallarıyla eşleştirir.

Temel MockK Sözdizimi

every { mock.method() } returns value bloğu “yöntem her çağrıldığında, değeri döndür” olarak okunur. Bu bildirimsel sözdizimi Kotlin stiline daha yakındır ve when() içindeki argüman sırasıyla ilgili karışıklığı ortadan kaldırır. Kotlin'in reified generics sayesinde, mock türü sınıfı açıkça belirtmeden otomatik olarak çıkarılır.

kotlin
val repository = mockk<UserRepository>()

// Stubbing: findById(1)'e her çağrı kullanıcıyı döndürür
every { repository.findById(1) } returns User("Alice")

// Çağrı ve doğrulama
val result = repository.findById(1)
assertEquals("Alice", result.name)

Gevşek Mock: Daha Az Tekrar Kodu

Her yöntemin açıkça yapılandırılması gereken Mockito'nun aksine, MockK relaxed mock'u destekler — herhangi bir yöntem için “makul” varsayılan değerler döndüren bir mock: List için boş liste, Int için 0, String için boş dize. Bu, hazırlık kodu miktarını önemli ölçüde azaltır.

kotlin
// Relaxed mock — tüm yöntemler varsayılan değerleri döndürür
val api = mockk<ApiService>(relaxed = true)

// Stubbing gerektirmez — boş liste döndürür
println(api.getUsers()) // []

Mock ve Gevşek Mock Oluşturma

MockK, mock nesneler oluşturmanın birkaç yolunu sunar: katı mock için mockk<T>() (her yöntem açıkça yapılandırılmalıdır), gevşek mock için mockk<T>(relaxed = true) ve gerçek bir nesne üzerinde casus oluşturmak için spyk(obj).

FonksiyonTürStubbing Olmadan Davranış
mockk()Katı mockStub'lanmamış yöntem çağrıldığında istisna fırlatır
mockk(relaxed = true)Gevşek mockVarsayılan değeri döndürür
spyk()CasusStub yapılandırılmamışsa gerçek yöntemi çağırır
slot()Argument CaptorDoğrulama için argümanı yakalar

Katı ve gevşek mock arasındaki seçim bağlama bağlıdır. Katı bir mock, testin davranışı tanımlanmamış yöntemleri kullanmamasını sağlar — bu güvenilirliği artırır. Gevşek mock, tüm bağımlılıkların önemli olmadığı hızlı test prototipleme için uygundur. Pratikte, katı bir mock ile başlamanız ve yalnızca stubbing testin kendisinden daha fazla satır kapladığında gevşeğe geçmeniz önerilir.

Stubbing: every Bloğu ile Davranış Yapılandırma

Every bloğu, MockK'daki merkezi stubbing yapısıdır. Lambda içinde, belirli argümanlarla bir yöntem çağrısı tanımlanır ve ardından returns ile bir değer döndürülür, throws ile bir istisna fırlatılır veya answers ile bir yanıt hesaplanır.

Farklı Stubbing Yöntemleri

MockK, test için gereken tüm senaryoları destekler: değer döndürme, istisna fırlatma, argümanlara dayalı yanıt hesaplama ve sırayla birden çok yanıt (çağrı sırası).

kotlin
// Değer döndürme
every { repo.findById(1) } returns User("Alice")

// İstisna fırlatma
every { repo.findById(999) } throws NotFoundException()

// Dinamik yanıt
every { repo.save(any()) } answers {
    val user = firstArg<User>()
    user.copy(id = 42)
}

// Yanıt sırası
every { repo.findAll() } returnsMany listOf(
    listOf(User("Alice")),
    listOf(User("Bob")),
    emptyList()
)

Eşyordamlar için Verify ve coVerify

Verify, MockK'da amaç olarak Mockito.verify()'e benzer, ancak Kotlin DSL kullanır: verify { mock.method() }. Suspend fonksiyonları için coVerify { mock.suspendMethod() } kullanılır, bu eşyordamlarla doğru şekilde çalışır ve özel bir çalıştırıcı gerektirmez.

Çağrı Sayısını Doğrulama

MockK, Mockito ile aynı değiştiricileri destekler: exactly(1), atLeast(2), atMost(5), wasNot(Called). Sözdizimi minimaldir — değiştirici verify { } içinde ilk argüman olarak iletilir.

kotlin
// Doğrulama: yöntem tam olarak 1 kez çağrıldı
verify(exactly = 1) { repo.save(any()) }

// Çağrı sırasını doğrula
verifySequence {
    repo.save(any())
    repo.flush()
}

// Suspend fonksiyonları için coVerify
coVerify { api.fetchUsers() }

Slot: Argüman Yakalama

Argüman doğrulaması için slot() kullanılır — ArgumentCaptor'un bir benzeri. Bir slot, çağrıdan önce bildirilir, every veya verify'ye iletilir ve test yürütmesinden sonra yakalanan değeri içerir.

kotlin
val userSlot = slot<User>()

verify { repo.save(capture(userSlot)) }

assertEquals("Alice", userSlot.captured.name)

MockK Ek Açıklamaları ve JUnit Entegrasyonu

MockK, JUnit 5'te başlatma yoluyla mock oluşturmak için @MockK ve @RelaxedMockK ek açıklamalarını sağlar. MockKExtension, her testten önce otomatik olarak mock'lar oluşturur ve sonra temizler — MockitoExtension'a benzer, ancak gevşek mod desteğiyle.

MockKExtension ile Örnek

@InjectMockKs ek açıklaması (veya açık nesne oluşturma ile alternatif @MockK), test edilen örneğe mock'ları enjekte eder. Bu, tekrar kodunu azaltır ve test kodunu daha temiz hale getirir.

kotlin
@ExtendWith(MockKExtension::class)
class UserServiceTest {

    @MockK
    lateinit var repository: UserRepository

    @InjectMockKs
    lateinit var service: UserService

    @Test
    fun `getUser returns user from repository`() {
        every { repository.findById(1) } returns User("Alice")
        assertEquals("Alice", service.getUser(1)?.name)
    }
}

MockK vs Mockito: Kotlin için Hangisini Seçmeli

Seçim ekip kompozisyonuna ve proje türüne bağlıdır. Mockito daha büyük bir ekosisteme, daha fazla örneğe ve entegrasyona sahiptir, ancak MockK daha temiz Kotlin sözdizimi ve dil özellikleri için yerel destek sunar. Yeni Kotlin projeleri için MockK daha deyimsel bir çözüm olarak önerilir.

KriterMockKMockito
SözdizimiKotlin DSL (every, verify)Java stili (when, thenReturn)
EşyordamlarcoEvery, coVerify (yerel)Ek kütüphane gerektirir
Final sınıfVarsayılan olarak desteklenirmockito-inline gerektirir
KMPDesteklenirDesteklenmez
Gevşek mockDahiliEşdeğeri yok
PopülerlikKotlin topluluğunda artıyorJava ve hibrit projelerde baskın

Saf Kotlin projeleri için (Java sınıfları olmadan), MockK tercih edilir: daha az tekrar kodu, yerel eşyordam desteği, final sınıflarla sürpriz yok. Hibrit projeler veya Java geçmişine sahip ekipler için Mockito çalışan bir seçenek olmaya devam ediyor — her iki kütüphane de farklı modüller aracılığıyla aynı projede kullanılabilir. Mockito'dan MockK'ya geçiş yaparken, @Mock ek açıklamalarını @MockK ile değiştirmek ve when().thenReturn() bloklarını every { } formatında yeniden yazmak yeterlidir.

Sıkça Sorulan Sorular

MockK'da gevşek mock'un normal mock'tan farkı nedir?

Relaxed mock, tüm stub'lanmamış yöntemler için istisna fırlatmadan varsayılan değerler (boş liste, 0, null) döndürür. Normal (katı) mock, her yöntemin açık stubbing'ini gerektirir — aksi halde test başarısız olur. Gevşek mock hızlı testler için uygundur, katı ise güvenilir testler için.

MockK'da genişletme fonksiyonları nasıl mocklanır?

MockK, mockkStatic() aracılığıyla genişletme fonksiyonlarının mocklanmasını destekler. Bu mümkündür çünkü Kotlin'deki genişletme fonksiyonları, alıcıyı ilk parametre olarak alan statik yöntemlerdir. Her genişletme fonksiyonu için, bildirildiği sınıfı belirtmeniz gerekir.

MockK, Kotlin Multiplatform ile çalışır mı?

Evet, MockK, ortak kod için Kotlin Multiplatform'u (KMP) destekler. JVM, Native ve JS platformlarında ortak API'yi kullanabilirsiniz: mockk(), every, verify. Bu, MockK'yı Mockito'nun çalışmadığı KMP projeleri için tek seçenek haline getirir.

MockK'da çağrı sırası nasıl doğrulanır?

verifySequence { } kullanın — çağrıların beklenen sırada kesin olarak belirtildiği bir blok. Gerçek sıra farklıysa, verifySequence ilk uyuşmayan çağrıyı belirten bir istisna fırlatır.

MockK ve Mockito aynı projede kullanılabilir mi?

Evet, teknik olarak mümkündür, ancak önerilmez. Bayt kodu enstrümantasyonu seviyesinde (ByteBuddy vs mockito-inline) çakışmalar oluşabilir. Bir proje zaten Mockito kullanıyorsa, MockK'ya geçiş modül izolasyonu yoluyla kademeli olabilir.

Özet

  • MockK — yerel dil desteğine sahip Kotlin-first bir mock kütüphanesi.
  • every { } — mock davranışını yapılandırmak için bildirimsel bir DSL.
  • coEvery / coVerify — ek bağımlılık olmadan eşyordamlarda suspend fonksiyonları için destek.
  • Relaxed mock — tekrar kodunu azaltan varsayılan değerlere sahip bir mock.
  • @MockK / @InjectMockKs — JUnit 5'te otomatik mock oluşturma için ek açıklamalar.
  • MockK vs Mockito — Saf Kotlin projeleri ve KMP için MockK tercih edilir.
  • verifySequence — yöntem çağrılarının kesin sırasının doğrulanması.

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun