Unit, Integration, and Platform-Specific Strategies
Testing is the backbone of reliable cross-platform apps. Kotlin Multiplatform (KMP) lets you write tests once for shared logic and adapt them for Android, iOS, and web. This chapter covers unit testing, integration testing, and mocking strategies to ensure your KMP apps work flawlessly across platforms.
Test shared business logic in commonTest
using Kotlin’s built-in kotlin.test
library.
Add to build.gradle.kts
:
kotlin {
sourceSets {
val commonTest by getting {
dependencies {
implementation(kotlin("test"))
}
}
}
}
// commonMain
fun add(a: Int, b: Int): Int = a + b
// commonTest
import kotlin.test.Test
import kotlin.test.assertEquals
class MathTests {
@Test
fun testAddition() {
assertEquals(5, add(2, 3))
}
}
Run Tests:
commonTest
→ Run Tests../gradlew test
.Test Android-specific code in androidTest
:
// androidMain
actual fun getPlatformName(): String = "Android"
// androidTest
import org.junit.Test
import kotlin.test.assertEquals
class AndroidPlatformTests {
@Test
fun testPlatformName() {
assertEquals("Android", getPlatformName())
}
}
Dependency:
androidTestImplementation("junit:junit:4.13.2")
Test iOS code in iosTest
:
// iosMain
actual fun getPlatformName(): String = "iOS"
// iosTest
import XCTest
class IosPlatformTests: XCTestCase {
func testPlatformName() {
XCTAssertEqual(getPlatformName(), "iOS")
}
}
Run iOS Tests:
./gradlew iosTest
.Verify end-to-end functionality, like API calls, using MockEngine to simulate responses.
// commonMain
suspend fun fetchUserData(client: HttpClient): String {
return client.get("https://api.example.com/user").body()
}
// commonTest
import io.ktor.client.engine.mock.*
import kotlin.test.Test
class NetworkingTests {
@Test
fun testFetchUserData() = runTest {
val mockEngine = MockEngine {
respond(
content = """{"id":1,"name":"Alex"}""",
status = HttpStatusCode.OK
)
}
val client = HttpClient(mockEngine)
assertEquals("""{"id":1,"name":"Alex"}""", fetchUserData(client))
}
}
Why MockEngine?
Mock dependencies to isolate components during testing.
Setup MockK:
dependencies {
commonTestImplementation("io.mockk:mockk-common:1.13.8")
}
Example:
interface UserRepository {
suspend fun getUser(id: Int): User
}
class UserServiceTest {
@Test
fun testFetchUser() = runTest {
val mockRepo = mockk<UserRepository>()
coEvery { mockRepo.getUser(1) } returns User(1, "Alex")
val service = UserService(mockRepo)
assertEquals("Alex", service.fetchUser(1))
}
}
Simplify testing with Koin’s lightweight DI framework.
Setup Koin:
dependencies {
implementation("io.insert-koin:koin-core:3.4.0")
}
Example:
class UserRepositoryTest : KoinTest {
private val repository: UserRepository by inject()
@Test
fun testUserFetching() {
assertEquals("Alex", repository.getUser(1).name)
}
}
kotlin.test
for shared logic unit tests.Introduction: Transform Your Cross-Platform Development with Material Design 3 Are you ready to revolutionize your… Read More
Jetpack Compose 1.8 rolls out handy features like Autofill integration, slick Text enhancements including auto-sizing… Read More
Reified Keyword in Kotlin: Simplify Your Generic Functions Kotlin's reified keyword lets your generic functions know the… Read More
Android Studio Cloud: Ditch the Setup, Code Anywhere (Seriously!) Alright, fellow Android devs, gather 'round… Read More