test: add unit tests for MatchRemoteDataSourceImpl
This commit is contained in:
parent
7f5f0dcf54
commit
e53d0c0903
4 changed files with 179 additions and 17 deletions
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
)
|
||||
}
|
||||
}
|
|
@ -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" }
|
||||
|
|
Loading…
Add table
Reference in a new issue