test: add unit tests for MatchRemoteDataSourceImpl

This commit is contained in:
Leonardo Murça 2025-07-19 16:23:23 -03:00
parent 7f5f0dcf54
commit e53d0c0903
4 changed files with 179 additions and 17 deletions

View file

@ -75,12 +75,15 @@ dependencies {
implementation(libs.coil.network)
ksp(libs.hilt.android.compiler)
testImplementation(libs.junit)
testImplementation(libs.kotlinx.coroutines.test)
testImplementation(libs.mockk)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
testImplementation(kotlin("test"))
}
fun getSecret(key: String): String {

View file

@ -1,17 +0,0 @@
package xyz.leomurca.csgomatches
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}

View file

@ -0,0 +1,172 @@
package xyz.leomurca.csgomatches.data.remote
import io.mockk.MockKAnnotations
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.every
import io.mockk.impl.annotations.InjectMockKs
import io.mockk.impl.annotations.RelaxedMockK
import io.mockk.mockk
import junit.framework.TestCase.assertTrue
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.setMain
import kotlinx.serialization.json.Json
import org.junit.After
import org.junit.Before
import org.junit.Test
import retrofit2.Response
import xyz.leomurca.csgomatches.data.model.ErrorDto
import xyz.leomurca.csgomatches.data.model.LeagueDto
import xyz.leomurca.csgomatches.data.model.MatchDto
import xyz.leomurca.csgomatches.data.model.SerieDto
import xyz.leomurca.csgomatches.data.model.TeamDetailsDto
import xyz.leomurca.csgomatches.domain.model.Resource
import kotlin.test.assertEquals
@OptIn(ExperimentalCoroutinesApi::class)
class MatchRemoteDataSourceImplTest {
@RelaxedMockK
private lateinit var api: MatchesApiService
@RelaxedMockK
private lateinit var json: Json
@InjectMockKs
private lateinit var dataSource: MatchRemoteDataSourceImpl
@Before
fun setUp() {
MockKAnnotations.init(this)
Dispatchers.setMain(StandardTestDispatcher())
}
@After
fun tearDown() {
Dispatchers.resetMain()
}
@Test
fun `upcomingMatches - response is successful - return Resource Success with matches`() =
runTest {
// Arrange
val matches = listOf(MATCH_DTO)
coEvery { api.upcomingMatches() } returns Response.success(matches)
// Act
val result = dataSource.upcomingMatches()
// Assert
coVerify(exactly = 1) {
api.upcomingMatches("running, not_started", false, "begin_at")
}
assertTrue(result is Resource.Success)
assertEquals(matches, (result as Resource.Success).data)
}
@Test
fun `upcomingMatches - response is an error - return api error with error body`() = runTest {
// Arrange
val errorDto = ErrorDto(message = "API failure")
coEvery { api.upcomingMatches() } returns mockk(relaxed = true) {
every { isSuccessful } returns false
}
every { json.decodeFromString<ErrorDto>(any()) } returns errorDto
// Act
val result = dataSource.upcomingMatches()
// Assert
assertTrue(result is Resource.Error)
assertEquals("API failure", (result as Resource.Error).message)
}
@Test
fun `upcomingMatches - response is an RuntimeException - returns Resource Error`() = runTest {
// Arrange
coEvery { api.upcomingMatches() } throws RuntimeException("Network error")
// Act
val result = dataSource.upcomingMatches()
// Assert
assertTrue(result is Resource.Error)
assertEquals("Network error", (result as Resource.Error).message)
}
@Test
fun `teamDetails - response is successful - returns Resource Success`() = runTest {
// Arrange
val teamDetails = listOf(TEAM_DETAILS_DTO)
coEvery { api.teamDetails("123") } returns Response.success(teamDetails)
// Act
val result = dataSource.teamDetails("123")
// Assert
assertTrue(result is Resource.Success)
assertEquals(teamDetails, (result as Resource.Success).data)
}
@Test
fun `teamDetails - response is an error - returns Resource Error`() = runTest {
// Arrange
val errorDto = ErrorDto(message = "Team not found")
coEvery { api.teamDetails("456") } returns mockk(relaxed = true) {
every { isSuccessful } returns false
}
every { json.decodeFromString<ErrorDto>(any()) } returns errorDto
// Act
val result = dataSource.teamDetails("456")
// Assert
assertTrue(result is Resource.Error)
assertEquals("Team not found", (result as Resource.Error).message)
}
@Test
fun `teamDetails - response is RuntimeException - returns Resource Error`() = runTest {
// Arrange
coEvery { api.teamDetails("789") } throws RuntimeException("Unknown error")
// Act
val result = dataSource.teamDetails("789")
// Assert
assertTrue(result is Resource.Error)
assertEquals("Unknown error", (result as Resource.Error).message)
}
companion object {
private val MATCH_DTO = MatchDto(
beginAt = null,
opponents = emptyList(),
league = LeagueDto(
id = 5078,
name = "United21",
imageUrl = "https://cdn.pandascore.co/images/league/image/5078/800px-united21_allmode-png"
),
serie = SerieDto(
id = 9519,
fullName = "Season 35 2025"
),
status = "not_started"
)
private val TEAM_DETAILS_DTO = TeamDetailsDto(
id = 123L,
name = "Team 1",
imageUrl = "",
players = emptyList()
)
}
}

View file

@ -18,6 +18,8 @@ kotlinxSerializationJson = "1.8.1"
okhttp = "4.12.0"
coil = "3.2.0"
hiltNavigation = "1.2.0"
mockk = "1.14.5"
coroutinesTest = "1.10.2"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@ -45,6 +47,8 @@ kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-
okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" }
coil-compose = { group = "io.coil-kt.coil3", name = "coil-compose", version.ref = "coil" }
coil-network = { group = "io.coil-kt.coil3", name = "coil-network-okhttp", version.ref = "coil" }
mockk = { group = "io.mockk", name = "mockk", version.ref = "mockk" }
kotlinx-coroutines-test= { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "coroutinesTest" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }