Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ADD Junit testing #25

Merged
merged 2 commits into from
Sep 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion build.module.feature-and-app.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,10 @@ dependencies {
implementation(libs.napier)
implementation(libs.activityCompose)
implementation(libs.hiltNavigationCompose)
}

testImplementation libs.junit
testImplementation libs.kotlinx.coroutines.test
testImplementation libs.turbine
testImplementation libs.mockk.android
testImplementation libs.mockk.agent
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package nl.q42.template.presentation.home

import app.cash.turbine.test
import io.mockk.coEvery
import io.mockk.every
import io.mockk.mockk
import junit.framework.TestCase.assertEquals
import kotlinx.coroutines.delay
import kotlinx.coroutines.test.runTest
import nl.q42.template.actionresult.domain.ActionResult
import nl.q42.template.domain.user.model.User
import nl.q42.template.domain.user.usecase.GetUserUseCase
import org.junit.Rule
import org.junit.Test
import kotlin.time.Duration.Companion.seconds


class HomeViewModelTest(){
@get:Rule
val mainDispatcherRule = MainDispatcherRule()
@Test
fun `WHEN I subscribe to uiState with a slow UserUseCase THEN I get the loading state and expected email address`() = runTest{
val getUserUseCaseMock: GetUserUseCase = mockk()
coEvery {getUserUseCaseMock.invoke() }.coAnswers {
// demonstration of test scheduler. This does not actually block the test for 4 seconds
delay(4.seconds)
ActionResult.Success(User("[email protected]"))
}

val viewModel = HomeViewModel(getUserUseCaseMock, mockk())

viewModel.uiState.test {
val expectedData: HomeViewState = HomeViewState.Data("[email protected]")

assertEquals(HomeViewState.Loading, awaitItem())
assertEquals(expectedData, awaitItem())
}
}

@Test
fun `WHEN I subscribe to uiState with a fast UserUseCase THEN I get expected email address immediately`() = runTest{
val getUserUseCaseMock: GetUserUseCase = mockk()
coEvery { getUserUseCaseMock.invoke() }.returns(
ActionResult.Success(User("[email protected]")
))


val viewModel = HomeViewModel(getUserUseCaseMock, mockk())

viewModel.uiState.test {
val expectedData: HomeViewState = HomeViewState.Data("[email protected]")
assertEquals(expectedData, awaitItem())
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package nl.q42.template.presentation.home

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.test.TestDispatcher
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.setMain
import org.junit.rules.TestWatcher
import org.junit.runner.Description

// Reusable JUnit4 TestRule to override the Main dispatcher
class MainDispatcherRule(
val testDispatcher: TestDispatcher = UnconfinedTestDispatcher(),
) : TestWatcher() {
override fun starting(description: Description) {
Dispatchers.setMain(testDispatcher)
}

override fun finished(description: Description) {
Dispatchers.resetMain()
}
}
10 changes: 10 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
[versions]
androidxCore = "1.9.0"
androidxLifecycle = "2.5.1"
kotlinxCoroutinesTest = "1.7.3"
junit = "4.13.2"
mockkAndroid = "1.13.5"
kotlinCompilerExtensionVersion = "1.4.4"
jvmTarget = "17"
kotlin = "1.8.10"
Expand All @@ -19,12 +22,18 @@ composePlatform = "2022.10.00"
activityCompose = "1.6.1"
hiltNavigationCompose = "1.0.0"
composeLifecycle = "2.6.0-beta01"
turbine = "1.0.0"
appcompat = "1.6.1"

[libraries]
androidxCoreKtx = { module = "androidx.core:core-ktx", version.ref = "androidxCore" }
androidxLifecycleKtx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "androidxLifecycle" }
hilt = { module = "com.google.dagger:hilt-android", version.ref = "hilt" }
hiltKapt = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hilt" }
junit = { module = "junit:junit", version.ref = "junit" }
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinxCoroutinesTest" }
mockk-agent = { module = "io.mockk:mockk-agent", version.ref = "mockkAndroid" }
mockk-android = { module = "io.mockk:mockk-android", version.ref = "mockkAndroid" }
retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
moshiRetrofitConverter = { module = "com.squareup.retrofit2:converter-moshi", version.ref = "retrofit" }
moshiKotlin = { module = "com.squareup.moshi:moshi-kotlin", version.ref = "moshi" }
Expand All @@ -44,6 +53,7 @@ composePlatform = { module = "androidx.compose:compose-bom", version.ref = "comp
activityCompose = { module = "androidx.activity:activity-compose", version.ref = "activityCompose" }
hiltNavigationCompose = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "hiltNavigationCompose" }
composeLifecycle = { module = "androidx.lifecycle:lifecycle-runtime-compose", version.ref = "composeLifecycle" }
turbine = { module = "app.cash.turbine:turbine", version.ref = "turbine" }


[plugins]
Expand Down
Loading