Curso De Testing — Kotlin
// Real code class ApiClient { suspend fun fetchUser(id: String): User { delay(3000) // Simulate network return User("John Doe") } }
Kotest will automatically generate 1000 random pairs of integers (including negative, zero, positive) and run the test. If it fails, it the input to the smallest failing case. Module 6: Testing Flows & SharedFlows Testing StateFlow and SharedFlow requires collecting values in a controlled way. Use TestCollector or launchIn . curso de testing kotlin
class MathProps : StringSpec({ "Addition should be commutative" { forAll { a: Int, b: Int -> // The property we want to test (a + b) == (b + a) } } "String length should be non-negative" { forAll<Int> { length -> val str = "x".repeat(length.coerceAtLeast(0)) str.length >= 0 } } }) // Real code class ApiClient { suspend fun
result.shouldBe(200) list.shouldContain("Kotlin") exception.shouldThrow<IllegalArgumentException> Kotlin Coroutines are amazing for production, but they are a nightmare for testing if you don't know the tricks. A naive test will pass when it should fail because the coroutine hasn't finished yet. The Golden Rule: runTest Never use Thread.sleep() in tests. Use kotlinx-coroutines-test . Use TestCollector or launchIn
@Test fun `verify API is called only once`() = runTest { // 1. Create mock val api = mockk<MyApi>() // 2. Stub a suspend function (coEvery) coEvery { api.getData() } returns "Mocked Response" val repo = Repository(api) // 3. Execute val result = repo.refreshData() // 4. Verify (coVerify) coVerify(exactly = 1) { api.getData() } result shouldBe "Mocked Response" } } Traditional testing (Example-based) says: "Give input 2+2, check output 4." Property-based testing says: "For ALL integers, addition should be commutative."
Use TestDispatcher and advanceUntilIdle() to control time precisely. Module 4: Mocking with MockK (Not Mockito) If you come from Java, you know Mockito. For Kotlin, you need MockK . Why? Because Mockito fails when dealing with final classes (Kotlin classes are final by default) and suspend functions. Mocking a suspend function import io.mockk.coEvery import io.mockk.coVerify import io.mockk.mockk class RepositoryTest {
@Test fun `fetchUser returns data after network call`() = runTest { val client = ApiClient() // This virtual time will skip the delay instantly. val user = client.fetchUser("123") assertEquals("John Doe", user.name) } }