Update unit tests
This commit is contained in:
@@ -4,7 +4,7 @@ import androidx.annotation.VisibleForTesting
|
||||
import androidx.paging.*
|
||||
import androidx.paging.LoadType.PREPEND
|
||||
import androidx.paging.LoadType.REFRESH
|
||||
import gq.kirmanak.mealient.data.configuration.AppDispatchers
|
||||
import gq.kirmanak.mealient.architecture.configuration.AppDispatchers
|
||||
import gq.kirmanak.mealient.data.recipes.db.RecipeStorage
|
||||
import gq.kirmanak.mealient.data.recipes.network.RecipeDataSource
|
||||
import gq.kirmanak.mealient.database.recipe.entity.RecipeSummaryEntity
|
||||
|
||||
@@ -5,8 +5,6 @@ import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import gq.kirmanak.mealient.architecture.configuration.BuildConfiguration
|
||||
import gq.kirmanak.mealient.data.configuration.AppDispatchers
|
||||
import gq.kirmanak.mealient.data.configuration.AppDispatchersImpl
|
||||
import gq.kirmanak.mealient.data.configuration.BuildConfigurationImpl
|
||||
import javax.inject.Singleton
|
||||
|
||||
@@ -17,8 +15,4 @@ interface ArchitectureModule {
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindBuildConfiguration(buildConfigurationImpl: BuildConfigurationImpl): BuildConfiguration
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindAppDispatchers(appDispatchersImpl: AppDispatchersImpl): AppDispatchers
|
||||
}
|
||||
@@ -14,9 +14,7 @@ import gq.kirmanak.mealient.test.RecipeImplTestData.MIX_CAKE_RECIPE_INSTRUCTION_
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.MIX_INSTRUCTION
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_FULL_RECIPE_INFO
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_RECIPE_SUMMARY_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.RECIPE_SUMMARY_CAKE
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.RECIPE_SUMMARY_PORRIDGE_V0
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.TEST_RECIPE_SUMMARIES
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.TEST_RECIPE_SUMMARY_ENTITIES
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
@@ -34,7 +32,7 @@ class RecipeStorageImplTest : HiltRobolectricTest() {
|
||||
|
||||
@Test
|
||||
fun `when saveRecipes then saves recipes`() = runTest {
|
||||
subject.saveRecipes(TEST_RECIPE_SUMMARIES)
|
||||
subject.saveRecipes(TEST_RECIPE_SUMMARY_ENTITIES)
|
||||
val actualTags = appDb.recipeDao().queryAllRecipes()
|
||||
assertThat(actualTags).containsExactly(
|
||||
CAKE_RECIPE_SUMMARY_ENTITY,
|
||||
@@ -44,15 +42,15 @@ class RecipeStorageImplTest : HiltRobolectricTest() {
|
||||
|
||||
@Test
|
||||
fun `when refreshAll then old recipes aren't preserved`() = runTest {
|
||||
subject.saveRecipes(TEST_RECIPE_SUMMARIES)
|
||||
subject.refreshAll(listOf(RECIPE_SUMMARY_CAKE))
|
||||
subject.saveRecipes(TEST_RECIPE_SUMMARY_ENTITIES)
|
||||
subject.refreshAll(listOf(CAKE_RECIPE_SUMMARY_ENTITY))
|
||||
val actual = appDb.recipeDao().queryAllRecipes()
|
||||
assertThat(actual).containsExactly(CAKE_RECIPE_SUMMARY_ENTITY)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when clearAllLocalData then recipes aren't preserved`() = runTest {
|
||||
subject.saveRecipes(TEST_RECIPE_SUMMARIES)
|
||||
subject.saveRecipes(TEST_RECIPE_SUMMARY_ENTITIES)
|
||||
subject.clearAllLocalData()
|
||||
val actual = appDb.recipeDao().queryAllRecipes()
|
||||
assertThat(actual).isEmpty()
|
||||
@@ -60,7 +58,7 @@ class RecipeStorageImplTest : HiltRobolectricTest() {
|
||||
|
||||
@Test
|
||||
fun `when saveRecipeInfo then saves recipe info`() = runTest {
|
||||
subject.saveRecipes(listOf(RECIPE_SUMMARY_CAKE))
|
||||
subject.saveRecipes(listOf(CAKE_RECIPE_SUMMARY_ENTITY))
|
||||
subject.saveRecipeInfo(CAKE_FULL_RECIPE_INFO)
|
||||
val actual = appDb.recipeDao().queryFullRecipeInfo("1")
|
||||
assertThat(actual).isEqualTo(FULL_CAKE_INFO_ENTITY)
|
||||
@@ -68,7 +66,7 @@ class RecipeStorageImplTest : HiltRobolectricTest() {
|
||||
|
||||
@Test
|
||||
fun `when saveRecipeInfo with two then saves second`() = runTest {
|
||||
subject.saveRecipes(listOf(RECIPE_SUMMARY_CAKE, RECIPE_SUMMARY_PORRIDGE_V0))
|
||||
subject.saveRecipes(TEST_RECIPE_SUMMARY_ENTITIES)
|
||||
subject.saveRecipeInfo(CAKE_FULL_RECIPE_INFO)
|
||||
subject.saveRecipeInfo(PORRIDGE_FULL_RECIPE_INFO)
|
||||
val actual = appDb.recipeDao().queryFullRecipeInfo("2")
|
||||
@@ -77,7 +75,7 @@ class RecipeStorageImplTest : HiltRobolectricTest() {
|
||||
|
||||
@Test
|
||||
fun `when saveRecipeInfo secondly then overwrites ingredients`() = runTest {
|
||||
subject.saveRecipes(listOf(RECIPE_SUMMARY_CAKE))
|
||||
subject.saveRecipes(listOf(CAKE_RECIPE_SUMMARY_ENTITY))
|
||||
subject.saveRecipeInfo(CAKE_FULL_RECIPE_INFO)
|
||||
val newRecipe = CAKE_FULL_RECIPE_INFO.copy(recipeIngredients = listOf(BREAD_INGREDIENT))
|
||||
subject.saveRecipeInfo(newRecipe)
|
||||
@@ -88,7 +86,7 @@ class RecipeStorageImplTest : HiltRobolectricTest() {
|
||||
|
||||
@Test
|
||||
fun `when saveRecipeInfo secondly then overwrites instructions`() = runTest {
|
||||
subject.saveRecipes(listOf(RECIPE_SUMMARY_CAKE))
|
||||
subject.saveRecipes(listOf(CAKE_RECIPE_SUMMARY_ENTITY))
|
||||
subject.saveRecipeInfo(CAKE_FULL_RECIPE_INFO)
|
||||
val newRecipe = CAKE_FULL_RECIPE_INFO.copy(recipeInstructions = listOf(MIX_INSTRUCTION))
|
||||
subject.saveRecipeInfo(newRecipe)
|
||||
|
||||
@@ -8,7 +8,6 @@ import gq.kirmanak.mealient.database.recipe.entity.RecipeSummaryEntity
|
||||
import gq.kirmanak.mealient.test.HiltRobolectricTest
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.CAKE_RECIPE_SUMMARY_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_RECIPE_SUMMARY_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.TEST_RECIPE_SUMMARIES
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.TEST_RECIPE_SUMMARY_ENTITIES
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.runTest
|
||||
@@ -27,28 +26,28 @@ class RecipePagingSourceFactoryImplTest : HiltRobolectricTest() {
|
||||
|
||||
@Test
|
||||
fun `when query is ca expect cake only is returned`() = runTest {
|
||||
storage.saveRecipes(TEST_RECIPE_SUMMARIES)
|
||||
storage.saveRecipes(TEST_RECIPE_SUMMARY_ENTITIES)
|
||||
subject.setQuery("ca")
|
||||
assertThat(queryRecipes()).isEqualTo(listOf(CAKE_RECIPE_SUMMARY_ENTITY))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when query is po expect porridge only is returned`() = runTest {
|
||||
storage.saveRecipes(TEST_RECIPE_SUMMARIES)
|
||||
storage.saveRecipes(TEST_RECIPE_SUMMARY_ENTITIES)
|
||||
subject.setQuery("po")
|
||||
assertThat(queryRecipes()).isEqualTo(listOf(PORRIDGE_RECIPE_SUMMARY_ENTITY))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when query is e expect cake and porridge are returned`() = runTest {
|
||||
storage.saveRecipes(TEST_RECIPE_SUMMARIES)
|
||||
storage.saveRecipes(TEST_RECIPE_SUMMARY_ENTITIES)
|
||||
subject.setQuery("e")
|
||||
assertThat(queryRecipes()).isEqualTo(TEST_RECIPE_SUMMARY_ENTITIES)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when query is null expect cake and porridge are returned`() = runTest {
|
||||
storage.saveRecipes(TEST_RECIPE_SUMMARIES)
|
||||
storage.saveRecipes(TEST_RECIPE_SUMMARY_ENTITIES)
|
||||
subject.setQuery(null)
|
||||
assertThat(queryRecipes()).isEqualTo(TEST_RECIPE_SUMMARY_ENTITIES)
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import gq.kirmanak.mealient.database.recipe.entity.RecipeSummaryEntity
|
||||
import gq.kirmanak.mealient.datasource.NetworkError.Unauthorized
|
||||
import gq.kirmanak.mealient.test.BaseUnitTest
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.TEST_RECIPE_SUMMARIES
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.TEST_RECIPE_SUMMARY_ENTITIES
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.impl.annotations.MockK
|
||||
@@ -42,7 +43,14 @@ class RecipesRemoteMediatorTest : BaseUnitTest() {
|
||||
@Before
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
subject = RecipesRemoteMediator(storage, dataSource, pagingSourceFactory, logger)
|
||||
subject = RecipesRemoteMediator(
|
||||
storage = storage,
|
||||
network = dataSource,
|
||||
pagingSourceFactory = pagingSourceFactory,
|
||||
logger = logger,
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
coEvery { dataSource.getFavoriteRecipes() } returns emptyList()
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -70,7 +78,7 @@ class RecipesRemoteMediatorTest : BaseUnitTest() {
|
||||
fun `when first load with refresh successful then recipes stored`() = runTest {
|
||||
coEvery { dataSource.requestRecipes(eq(0), eq(6)) } returns TEST_RECIPE_SUMMARIES
|
||||
subject.load(REFRESH, pagingState())
|
||||
coVerify { storage.refreshAll(eq(TEST_RECIPE_SUMMARIES)) }
|
||||
coVerify { storage.refreshAll(eq(TEST_RECIPE_SUMMARY_ENTITIES)) }
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -132,9 +140,7 @@ class RecipesRemoteMediatorTest : BaseUnitTest() {
|
||||
subject.load(REFRESH, pagingState())
|
||||
coEvery { dataSource.requestRecipes(any(), any()) } throws Unauthorized(RuntimeException())
|
||||
subject.load(APPEND, pagingState())
|
||||
coVerify {
|
||||
storage.refreshAll(TEST_RECIPE_SUMMARIES)
|
||||
}
|
||||
coVerify { storage.refreshAll(TEST_RECIPE_SUMMARY_ENTITIES) }
|
||||
}
|
||||
|
||||
private fun pagingState(
|
||||
|
||||
@@ -76,7 +76,7 @@ class ModelMappingsTest : BaseUnitTest() {
|
||||
|
||||
@Test
|
||||
fun `when summary info to entity expect correct entity`() {
|
||||
val actual = RECIPE_SUMMARY_PORRIDGE_V0.toRecipeSummaryEntity()
|
||||
val actual = RECIPE_SUMMARY_PORRIDGE_V0.toRecipeSummaryEntity(isFavorite = false)
|
||||
assertThat(actual).isEqualTo(PORRIDGE_RECIPE_SUMMARY_ENTITY)
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,7 @@ object RecipeImplTestData {
|
||||
dateAdded = LocalDate.parse("2021-11-13"),
|
||||
dateUpdated = LocalDateTime.parse("2021-11-13T15:30:13"),
|
||||
imageId = "cake",
|
||||
isFavorite = false,
|
||||
)
|
||||
|
||||
val PORRIDGE_RECIPE_SUMMARY_ENTITY = RecipeSummaryEntity(
|
||||
@@ -90,6 +91,7 @@ object RecipeImplTestData {
|
||||
dateAdded = LocalDate.parse("2021-11-12"),
|
||||
dateUpdated = LocalDateTime.parse("2021-10-13T17:35:23"),
|
||||
imageId = "porridge",
|
||||
isFavorite = false,
|
||||
)
|
||||
|
||||
val TEST_RECIPE_SUMMARY_ENTITIES =
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package gq.kirmanak.mealient.data.configuration
|
||||
package gq.kirmanak.mealient.architecture.configuration
|
||||
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.MainCoroutineDispatcher
|
||||
|
||||
interface AppDispatchers {
|
||||
val io: CoroutineDispatcher
|
||||
val main: MainCoroutineDispatcher
|
||||
val main: CoroutineDispatcher
|
||||
val default: CoroutineDispatcher
|
||||
val unconfined: CoroutineDispatcher
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package gq.kirmanak.mealient.data.configuration
|
||||
package gq.kirmanak.mealient.architecture.configuration
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import javax.inject.Inject
|
||||
@@ -0,0 +1,16 @@
|
||||
package gq.kirmanak.mealient.architecture.configuration
|
||||
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
interface ArchitectureModule {
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindAppDispatchers(appDispatchersImpl: AppDispatchersImpl): AppDispatchers
|
||||
}
|
||||
@@ -15,6 +15,7 @@ android {
|
||||
|
||||
dependencies {
|
||||
implementation(project(":logging"))
|
||||
implementation(project(":architecture"))
|
||||
|
||||
implementation(libs.google.dagger.hiltAndroid)
|
||||
kapt(libs.google.dagger.hiltCompiler)
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package gq.kirmanak.mealient.test
|
||||
|
||||
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
||||
import gq.kirmanak.mealient.architecture.configuration.AppDispatchers
|
||||
import gq.kirmanak.mealient.logging.Logger
|
||||
import io.mockk.MockKAnnotations
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
import kotlinx.coroutines.test.UnconfinedTestDispatcher
|
||||
import kotlinx.coroutines.test.resetMain
|
||||
import kotlinx.coroutines.test.setMain
|
||||
@@ -20,10 +23,18 @@ open class BaseUnitTest {
|
||||
|
||||
protected val logger: Logger = FakeLogger()
|
||||
|
||||
lateinit var dispatchers: AppDispatchers
|
||||
|
||||
@Before
|
||||
open fun setUp() {
|
||||
MockKAnnotations.init(this)
|
||||
Dispatchers.setMain(UnconfinedTestDispatcher())
|
||||
dispatchers = object : AppDispatchers {
|
||||
override val io: CoroutineDispatcher = StandardTestDispatcher()
|
||||
override val main: CoroutineDispatcher = StandardTestDispatcher()
|
||||
override val default: CoroutineDispatcher = StandardTestDispatcher()
|
||||
override val unconfined: CoroutineDispatcher = StandardTestDispatcher()
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
|
||||
Reference in New Issue
Block a user