Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Mocking Kotlin with MockK

Mocking Kotlin with MockK

Hadi Tok

March 23, 2019
Tweet

More Decks by Hadi Tok

Other Decks in Programming

Transcript

  1. KOTLIN'DE MOCKLAMA VE MOCKK

  2. BEN KIMIM ➤ Lead Android Dev @CizitzenMe ➤ https://haditok.com

  3. UNIT TESTING NEDIR? ➤ Unit: En küçük test edilebilir birim

    (Class, Function) ➤ Birimler diğer birimlerden bağımısız olarak test edilir. ➤ Diğer birimler Mock veya Fake ile değiştirilir.
  4. TEST EDILEBILIR KOD ➤ Separations of concerns ➤ Dependency injection

    ➤ Clean code
  5. FAKE ➤ Anlamı: Sahte ➤ Daha önceden belirlenmiş değerleri dönerek

    kontrollü bir ortam sağlama
  6. MOCKING NEDIR? Kuzey Alaycı kuşu (Mimus polyglottos)

  7. MOCK ➤ Anlamı: Taklit, Alay ➤ Unit testlerde test ettiğimiz

    birimin ihtiyacı olan objeleri objeleri taklit ederek, bu objeler üzerinde tam kontrol sağlar
  8. NELERI KONTROL EDIYORUZ? ➤ Değişken ve fonksiyonların döneceği değerleri ➤

    Fonksiyonların doğru parametreler ile çağırılıp çağrılmadığını
  9. NEDEN MOCKK ➤ Saf Kotlin için bir framework ➤ Domain

    Specific Language(DSL)
  10. data class User(val userId: String, val userName: String)

  11. data class User(val userId: String, val userName: String) interface UserApi

    { fun deleteUser(userId: String): Boolean }
  12. data class User(val userId: String, val userName: String) interface UserApi

    { fun deleteUser(userId: String): Boolean } class UserManager(private val userApi: UserApi) { fun deleteUser(user: User): Boolean { return userApi.deleteUser(user.userId) } }
  13. @Test fun basicTest() { val userApi: UserApi = mockk() }

  14. @Test fun basicTest() { val userApi: UserApi = mockk() val

    userManager = UserManager(userApi) }
  15. @Test fun basicTest() { val userApi: UserApi = mockk() val

    userManager = UserManager(userApi) val userId = "123" val user: User = mockk() every { user.userId } returns userId }
  16. @Test fun basicTest() { val userApi: UserApi = mockk() val

    userManager = UserManager(userApi) val userId = "123" val user: User = mockk() every { user.userId } returns userId every { userApi.deleteUser(userId) } returns true }
  17. @Test fun basicTest() { val userApi: UserApi = mockk() val

    userManager = UserManager(userApi) val userId = "123" val user: User = mockk() every { user.userId } returns userId every { userApi.deleteUser(userId) } returns true val result = userManager.deleteUser(user) }
  18. @Test fun basicTest() { val userApi: UserApi = mockk() val

    userManager = UserManager(userApi) val userId = "123" val user: User = mockk() every { user.userId } returns userId every { userApi.deleteUser(userId) } returns true val result = userManager.deleteUser(user) assert(result).toBe(true) }
  19. @Test fun basicTest() { val userApi: UserApi = mockk() val

    userManager = UserManager(userApi) val userId = "123" val user: User = mockk() every { user.userId } returns userId every { userApi.deleteUser(userId) } returns true val result = userManager.deleteUser(user) assert(result).toBe(true) verify { userApi.deleteUser(userId) } }
  20. @Test fun basicTest() { val userApi: UserApi = mockk() val

    userManager = UserManager(userApi) val userId = "123" val user: User = mockk() every { user.userId } returns userId every { userApi.deleteUser(userId) } returns true val result = userManager.deleteUser(user) assert(result).toBe(true) verify { userApi.deleteUser(match { it.startsWith("12") }) } }
  21. @Test fun basicTest() { val userApi: UserApi = mockk() val

    userManager = UserManager(userApi) val userId = "123" val user: User = mockk() every { user.userId } returns userId every { userApi.deleteUser(userId) } returns true val result = userManager.deleteUser(user) assert(result).toBe(true) verify { userApi.deleteUser(any()) } }
  22. @MockK lateinit var userApi: UserApi @MockK lateinit var user: User

    val userId = “123" lateinit var userManager:UserManager @Before fun initTests() { MockKAnnotations.init(this) userManager = UserManager(userApi) every { user.userId } returns userId } @Test fun basicTest() { every { userApi.deleteUser(userId) } returns true val result = userManager.deleteUser(user) assert(result).toBe(true) verify { userApi.deleteUser(userId) } }
  23. OBJECT MOCK

  24. object Calculator { fun add(first: Int, second: Int) = first

    + second }
  25. object Calculator { fun add(first: Int, second: Int) = first

    + second } @Test fun objectMock() { val result = Calculator.add(1, 2) assert(result).toBe(3) }
  26. object Calculator { fun add(first: Int, second: Int) = first

    + second } @Test fun objectMock() { val result = Calculator.add(1, 2) assert(result).toBe(3) mockkObject(Calculator) }
  27. object Calculator { fun add(first: Int, second: Int) = first

    + second } @Test fun objectMock() { val result = Calculator.add(1, 2) assert(result).toBe(3) mockkObject(Calculator) every { Calculator.add(1, 2) } returns 42 }
  28. object Calculator { fun add(first: Int, second: Int) = first

    + second } @Test fun objectMock() { val result = Calculator.add(1, 2) assert(result).toBe(3) mockkObject(Calculator) every { Calculator.add(1, 2) } returns 41 val mockedResult = Calculator.add(1, 2) }
  29. object Calculator { fun add(first: Int, second: Int) = first

    + second } @Test fun objectMock() { val result = Calculator.add(1, 2) assert(result).toBe(3) mockkObject(Calculator) every { Calculator.add(1, 2) } returns 41 val mockedResult = Calculator.add(1, 2) assert(mockedResult).toBe(42) }
  30. STATIC MOCK

  31. public class CalculatorStatic { static int add(int first, int second){

    return first+second; } }
  32. @Test fun staticMock() { val result = CalculatorStatic.add(1, 2) assert(result).toBe(3)

    }
  33. @Test fun staticMock() { val result = CalculatorStatic.add(1, 2) assert(result).toBe(3)

    mockkStatic(CalculatorStatic ::class) }
  34. @Test fun staticMock() { val result = CalculatorStatic.add(1, 2) assert(result).toBe(3)

    mockkStatic(CalculatorStatic ::class) every { CalculatorStatic.add(1, 2) } returns 42 }
  35. @Test fun staticMock() { val result = CalculatorStatic.add(1, 2) assert(result).toBe(3)

    mockkStatic(CalculatorStatic ::class) every { CalculatorStatic.add(1, 2) } returns 41 val mockedResult = CalculatorStatic.add(1, 2) }
  36. @Test fun staticMock() { val result = CalculatorStatic.add(1, 2) assert(result).toBe(3)

    mockkStatic(CalculatorStatic ::class) every { CalculatorStatic.add(1, 2) } returns 41 val mockedResult = CalculatorStatic.add(1, 2) assert(mockedResult).toBe(42) }
  37. COROUTINES

  38. data class User(val userId: String, val userName: String) interface UserApi

    { suspend fun deleteUser(userId: String): Boolean }
  39. data class User(val userId: String, val userName: String) interface UserApi

    { suspend fun deleteUser(userId: String): Boolean } class UserManager(private val userApi: UserApi) { suspend fun deleteUser(user: User): Boolean { return userApi.deleteUser(user.userId) } }
  40. @Test fun basicTest() = runBlocking { }

  41. @Test fun basicTest() = runBlocking { val userApi: UserApi =

    mockk() val userManager = UserManager(userApi) val userId = "123" val user: User = mockk() every { user.userId } returns userId }
  42. @Test fun basicTest() = runBlocking { val userApi: UserApi =

    mockk() val userManager = UserManager(userApi) val userId = "123" val user: User = mockk() every { user.userId } returns userId coEvery { userApi.deleteUser(userId) } returns true }
  43. @Test fun basicTest() = runBlocking { val userApi: UserApi =

    mockk() val userManager = UserManager(userApi) val userId = “123" val user: User = mockk() every { user.userId } returns userId coEvery { userApi.deleteUser(userId) } returns true val result = userManager.deleteUser(user) }
  44. @Test fun basicTest() = runBlocking { val userApi: UserApi =

    mockk() val userManager = UserManager(userApi) val userId = “123" val user: User = mockk() every { user.userId } returns userId coEvery { userApi.deleteUser(userId) } returns true val result = userManager.deleteUser(user) assert(result).toBe(true) coVerify { userApi.deleteUser(userId) } }
  45. LIMITASYONLAR ➤ final static ➤ inline fonksiyonlar

  46. UNIT TESTS WITHOUT INTEGRATION TESTS (ZORUNLU GIF)

  47. TEŞEKKÜRLER HTTPS://MOCKK.IO/