REDI-100: adopt MockK and rewrite unit tests to use it
Replace the hand-written CharacterRepository fakes in the ViewModel and UseCase unit tests with MockK mocks (coEvery / coVerify). This is a deliberate showcase of MockK and intentionally diverges from the repo's "prefer fakes over mocks" guidance. - Add io.mockk:mockk 1.14.3 to the version catalog and the unit-test bundle; add it explicitly to DomainModuleConventionPlugin (domain does not consume the bundle). - CharacterListViewModelTest: strict mockk, per-page coEvery stubs; the paging/in-flight guards are expressed via coVerify(exactly = ...) and coVerifyOrder instead of fake call counters. - CharacterDetailViewModelTest: relaxed mockk so "missing id" needs no stubbing; explicit coEvery elsewhere. - GetCharactersPageUseCaseTest: mockk + coVerify replaces the inline fake. - Move character()/characterDetails() fixtures to CharacterFixtures.kt and delete FakeCharacterRepository.kt. - NetworkCharacterRepositoryTest stays on Ktor MockEngine (MockK is for Kotlin collaborator interfaces, not the HTTP transport).
This commit is contained in:
@@ -7,23 +7,29 @@ import com.example.architecture.core.domain.DataError
|
||||
import com.example.architecture.core.domain.Result
|
||||
import com.example.architecture.feature.characters.domain.CharacterRepository
|
||||
import com.example.architecture.feature.characters.domain.model.Character
|
||||
import com.example.architecture.feature.characters.domain.model.CharacterDetails
|
||||
import com.example.architecture.feature.characters.domain.model.CharacterStatus
|
||||
import com.example.architecture.feature.characters.domain.model.CharactersPage
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
/**
|
||||
* Tests for the (thin pass-through) [GetCharactersPageUseCase]: it must forward the requested page to
|
||||
* the repository and return its result verbatim — success and error alike. Pure JVM test on the
|
||||
* JUnit 5 platform (see DomainModuleConventionPlugin); collaborator is a hand-written fake.
|
||||
* JUnit 5 platform (see DomainModuleConventionPlugin); the [CharacterRepository] collaborator is a
|
||||
* MockK mock, stubbed with `coEvery` and verified with `coVerify`.
|
||||
*/
|
||||
class GetCharactersPageUseCaseTest {
|
||||
|
||||
private val repository = mockk<CharacterRepository>()
|
||||
private val useCase = GetCharactersPageUseCase(repository)
|
||||
|
||||
@Test
|
||||
fun `returns the repository page on success`() = runBlocking {
|
||||
val page = CharactersPage(characters = listOf(domainCharacter(1)), nextPage = 2)
|
||||
val useCase = GetCharactersPageUseCase(FakeCharacterRepository(pageResult = Result.Success(page)))
|
||||
coEvery { repository.getCharacters(1) } returns Result.Success(page)
|
||||
|
||||
val result = useCase(page = 1)
|
||||
|
||||
@@ -32,9 +38,7 @@ class GetCharactersPageUseCaseTest {
|
||||
|
||||
@Test
|
||||
fun `propagates the repository error`() = runBlocking {
|
||||
val useCase = GetCharactersPageUseCase(
|
||||
FakeCharacterRepository(pageResult = Result.Error(DataError.Network.SERVER_ERROR)),
|
||||
)
|
||||
coEvery { repository.getCharacters(1) } returns Result.Error(DataError.Network.SERVER_ERROR)
|
||||
|
||||
val result = useCase(page = 1)
|
||||
|
||||
@@ -44,29 +48,12 @@ class GetCharactersPageUseCaseTest {
|
||||
|
||||
@Test
|
||||
fun `forwards the requested page number`() = runBlocking {
|
||||
val fake = FakeCharacterRepository(
|
||||
pageResult = Result.Success(CharactersPage(characters = emptyList(), nextPage = null)),
|
||||
)
|
||||
val useCase = GetCharactersPageUseCase(fake)
|
||||
coEvery { repository.getCharacters(any()) } returns
|
||||
Result.Success(CharactersPage(characters = emptyList(), nextPage = null))
|
||||
|
||||
useCase(page = 7)
|
||||
|
||||
assertThat(fake.lastRequestedPage).isEqualTo(7)
|
||||
}
|
||||
|
||||
private class FakeCharacterRepository(
|
||||
private val pageResult: Result<CharactersPage, DataError>,
|
||||
) : CharacterRepository {
|
||||
var lastRequestedPage: Int? = null
|
||||
private set
|
||||
|
||||
override suspend fun getCharacters(page: Int): Result<CharactersPage, DataError> {
|
||||
lastRequestedPage = page
|
||||
return pageResult
|
||||
}
|
||||
|
||||
override suspend fun getCharacterDetails(id: Int): Result<CharacterDetails, DataError> =
|
||||
Result.Error(DataError.Network.NOT_FOUND)
|
||||
coVerify(exactly = 1) { repository.getCharacters(7) }
|
||||
}
|
||||
|
||||
private fun domainCharacter(id: Int) = Character(
|
||||
|
||||
Reference in New Issue
Block a user