diff --git a/app/build.gradle b/app/build.gradle index 7371495..107f2db 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -51,6 +51,13 @@ android { java.srcDirs += "src/sharedTest/java" java.srcDirs += "src/robolectricTest/java" } + testHilt { + java.srcDirs += "src/robolectricTestHilt/java" + resources.srcDirs += "src/robolectricTestHilt/resources" + } + testKoin { + java.srcDirs += "src/robolectricTestKoin/java" + } } // needed for androidTest @@ -89,9 +96,7 @@ dependencies { koinImplementation "io.insert-koin:koin-android:$koin_version" // Hilt -// hiltImplementation "com.google.dagger:hilt-android:$hilt_version" implementation "com.google.dagger:hilt-android:$hilt_version" -// implementation "com.google.dagger:hilt-core:$hilt_version" kaptHilt "com.google.dagger:hilt-compiler:$hilt_version" hiltImplementation "androidx.activity:activity-ktx:$activity_ktx_version" diff --git a/app/src/robolectricTestHilt/java/org/fnives/test/showcase/favourite/FavouriteContentLocalStorageImplTest.kt b/app/src/robolectricTestHilt/java/org/fnives/test/showcase/favourite/FavouriteContentLocalStorageImplTest.kt new file mode 100644 index 0000000..967962f --- /dev/null +++ b/app/src/robolectricTestHilt/java/org/fnives/test/showcase/favourite/FavouriteContentLocalStorageImplTest.kt @@ -0,0 +1,97 @@ +package org.fnives.test.showcase.favourite + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import dagger.hilt.android.testing.HiltAndroidRule +import dagger.hilt.android.testing.HiltAndroidTest +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.async +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.take +import kotlinx.coroutines.flow.toList +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.test.TestCoroutineDispatcher +import org.fnives.test.showcase.core.storage.content.FavouriteContentLocalStorage +import org.fnives.test.showcase.model.content.ContentId +import org.fnives.test.showcase.storage.database.DatabaseInitialization +import org.junit.Assert +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import javax.inject.Inject + +@Suppress("TestFunctionName") +@OptIn(ExperimentalCoroutinesApi::class) +@RunWith(AndroidJUnit4::class) +@HiltAndroidTest +internal class FavouriteContentLocalStorageImplTest { + + @get:Rule + val hiltRule = HiltAndroidRule(this) + + @Inject + lateinit var sut : FavouriteContentLocalStorage + private lateinit var testDispatcher: TestCoroutineDispatcher + + @Before + fun setUp() { + testDispatcher = TestCoroutineDispatcher() + DatabaseInitialization.dispatcher = testDispatcher + hiltRule.inject() + } + + @Test + fun GIVEN_content_id_WHEN_added_to_Favourite_THEN_it_can_be_read_out() = runBlocking { + val expected = listOf(ContentId("a")) + + sut.markAsFavourite(ContentId("a")) + val actual = sut.observeFavourites().first() + + Assert.assertEquals(expected, actual) + } + + @Test + fun GIVEN_content_id_added_WHEN_removed_to_Favourite_THEN_it_no_longer_can_be_read_out() = + runBlocking { + val expected = listOf() + sut.markAsFavourite(ContentId("b")) + + sut.deleteAsFavourite(ContentId("b")) + val actual = sut.observeFavourites().first() + + Assert.assertEquals(expected, actual) + } + + @Test + fun GIVEN_empty_database_WHILE_observing_content_WHEN_favourite_added_THEN_change_is_emitted() = + runBlocking { + val expected = listOf(listOf(), listOf(ContentId("a"))) + + val testDispatcher = TestCoroutineDispatcher() + val actual = async(testDispatcher) { + sut.observeFavourites().take(2).toList() + } + testDispatcher.advanceUntilIdle() + + sut.markAsFavourite(ContentId("a")) + + Assert.assertEquals(expected, actual.await()) + } + + @Test + fun GIVEN_non_empty_database_WHILE_observing_content_WHEN_favourite_removed_THEN_change_is_emitted() = + runBlocking { + val expected = listOf(listOf(ContentId("a")), listOf()) + sut.markAsFavourite(ContentId("a")) + + val testDispatcher = TestCoroutineDispatcher() + val actual = async(testDispatcher) { + sut.observeFavourites().take(2).toList() + } + testDispatcher.advanceUntilIdle() + + sut.deleteAsFavourite(ContentId("a")) + + Assert.assertEquals(expected, actual.await()) + } +} diff --git a/app/src/robolectricTestHilt/resources/org/fnives/test/showcase/favourite/robolectric.properties b/app/src/robolectricTestHilt/resources/org/fnives/test/showcase/favourite/robolectric.properties new file mode 100644 index 0000000..cd922e4 --- /dev/null +++ b/app/src/robolectricTestHilt/resources/org/fnives/test/showcase/favourite/robolectric.properties @@ -0,0 +1,4 @@ +sdk=28 +shadows=org.fnives.test.showcase.testutils.shadow.ShadowSnackbar +instrumentedPackages=androidx.loader.content +application=dagger.hilt.android.testing.HiltTestApplication diff --git a/app/src/robolectricTest/java/org/fnives/test/showcase/favourite/FavouriteContentLocalStorageImplTest.kt b/app/src/robolectricTestKoin/java/org/fnives/test/showcase/favourite/FavouriteContentLocalStorageImplTest.kt similarity index 100% rename from app/src/robolectricTest/java/org/fnives/test/showcase/favourite/FavouriteContentLocalStorageImplTest.kt rename to app/src/robolectricTestKoin/java/org/fnives/test/showcase/favourite/FavouriteContentLocalStorageImplTest.kt diff --git a/app/src/sharedTest/java/org/fnives/test/showcase/testutils/ReloadKoinModulesIfNecessaryTestRule.kt b/app/src/sharedTest/java/org/fnives/test/showcase/testutils/ReloadKoinModulesIfNecessaryTestRule.kt index 5e65a0f..4e48eb4 100644 --- a/app/src/sharedTest/java/org/fnives/test/showcase/testutils/ReloadKoinModulesIfNecessaryTestRule.kt +++ b/app/src/sharedTest/java/org/fnives/test/showcase/testutils/ReloadKoinModulesIfNecessaryTestRule.kt @@ -1,33 +1,29 @@ package org.fnives.test.showcase.testutils -import androidx.test.core.app.ApplicationProvider -import org.fnives.test.showcase.TestShowcaseApplication -import org.fnives.test.showcase.di.BaseUrlProvider -import org.fnives.test.showcase.di.createAppModules +//import org.fnives.test.showcase.di.createAppModules +//import org.koin.android.ext.koin.androidContext import org.junit.rules.TestRule import org.junit.runner.Description import org.junit.runners.model.Statement -import org.koin.android.ext.koin.androidContext -import org.koin.core.context.GlobalContext -import org.koin.core.context.startKoin -import org.koin.core.context.stopKoin +//import org.koin.core.context.GlobalContext +//import org.koin.core.context.startKoin class ReloadKoinModulesIfNecessaryTestRule : TestRule { override fun apply(base: Statement, description: Description): Statement = object : Statement() { override fun evaluate() { - if (GlobalContext.getOrNull() == null) { - val application = ApplicationProvider.getApplicationContext() - startKoin { - androidContext(application) - modules(createAppModules(BaseUrlProvider.get())) - } +// if (GlobalContext.getOrNull() == null) { +// val application = ApplicationProvider.getApplicationContext() +// startKoin { +// androidContext(application) +// modules(createAppModules(BaseUrlProvider.get())) +// } } - try { - base.evaluate() - } finally { - stopKoin() - } - } +// try { +// base.evaluate() +// } finally { +// stopKoin() +// } +// } } } diff --git a/app/src/test/java/org/fnives/test/showcase/di/DITest.kt b/app/src/test/java/org/fnives/test/showcase/di/DITest.kt index 1a88d3d..df77d80 100644 --- a/app/src/test/java/org/fnives/test/showcase/di/DITest.kt +++ b/app/src/test/java/org/fnives/test/showcase/di/DITest.kt @@ -1,7 +1,6 @@ package org.fnives.test.showcase.di import android.content.Context -import org.fnives.test.showcase.model.network.BaseUrl import org.fnives.test.showcase.testutils.TestMainDispatcher import org.fnives.test.showcase.ui.auth.AuthViewModel import org.fnives.test.showcase.ui.home.MainViewModel @@ -10,11 +9,8 @@ import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith -import org.koin.android.ext.koin.androidContext -import org.koin.core.context.startKoin import org.koin.core.context.stopKoin import org.koin.test.KoinTest -import org.koin.test.check.checkModules import org.koin.test.inject import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.doReturn @@ -42,20 +38,20 @@ class DITest : KoinTest { fun verifyStaticModules() { val mockContext = mock() whenever(mockContext.getSharedPreferences(anyOrNull(), anyOrNull())).doReturn(mock()) - checkModules { - androidContext(mockContext) - modules(createAppModules(BaseUrl("https://a.com/"))) - } +// checkModules { +// androidContext(mockContext) +// modules(createAppModules(BaseUrl("https://a.com/"))) +// } } @Test fun verifyViewModelModules() { val mockContext = mock() whenever(mockContext.getSharedPreferences(anyOrNull(), anyOrNull())).doReturn(mock()) - startKoin { - androidContext(mockContext) - modules(createAppModules(BaseUrl("https://a.com/"))) - } +// startKoin { +// androidContext(mockContext) +// modules(createAppModules(BaseUrl("https://a.com/"))) +// } authViewModel mainViewModel splashViewModel