Skip to content
This repository has been archived by the owner on Feb 20, 2023. It is now read-only.

Commit

Permalink
For #21733 - Replace mock of an interface with mock of a fake.
Browse files Browse the repository at this point in the history
(cherry picked from commit 4d5bd9e)
  • Loading branch information
Mugurell authored and mergify-bot committed Nov 4, 2021
1 parent a5540a0 commit 0cba75c
Showing 1 changed file with 39 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import io.mockk.mockk
import io.mockk.spyk
import io.mockk.verify
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.TestCoroutineScope
import mozilla.components.service.pocket.PocketRecommendedStory
Expand Down Expand Up @@ -59,6 +61,7 @@ class PocketUpdatesMiddlewareTest {
}

@Test
@Suppress("UNCHECKED_CAST")
fun `WHEN PocketStoriesCategoriesChange is dispatched THEN intercept and dispatch PocketStoriesCategoriesSelectionsChange`() {
val persistedSelectedCategory: SelectedPocketStoriesCategory = mockk {
every { name } returns "testCategory"
Expand All @@ -67,9 +70,10 @@ class PocketUpdatesMiddlewareTest {
val persistedSelectedCategories: SelectedPocketStoriesCategories = mockk {
every { valuesList } returns mutableListOf(persistedSelectedCategory)
}
val dataStore: DataStore<SelectedPocketStoriesCategories> = mockk {
every { data } returns flowOf(persistedSelectedCategories)
}
val dataStore: DataStore<SelectedPocketStoriesCategories> =
mockk<FakeDataStore<SelectedPocketStoriesCategories>>(relaxed = true) {
every { data } returns flowOf(persistedSelectedCategories)
} as DataStore<SelectedPocketStoriesCategories>
val currentCategories = listOf(mockk<PocketRecommendedStoriesCategory>())
val pocketMiddleware = PocketUpdatesMiddleware(TestCoroutineScope(), mockk(), dataStore)
val homeStore = spyk(
Expand All @@ -96,10 +100,13 @@ class PocketUpdatesMiddlewareTest {
}

@Test
@Suppress("UNCHECKED_CAST")
fun `WHEN SelectPocketStoriesCategory is dispatched THEN persist details in DataStore`() {
val categ1 = PocketRecommendedStoriesCategory("categ1")
val categ2 = PocketRecommendedStoriesCategory("categ2")
val dataStore: DataStore<SelectedPocketStoriesCategories> = mockk(relaxed = true)
val dataStore: DataStore<SelectedPocketStoriesCategories> =
mockk<FakeDataStore<SelectedPocketStoriesCategories>>(relaxed = true) as
DataStore<SelectedPocketStoriesCategories>
val pocketMiddleware = PocketUpdatesMiddleware(TestCoroutineScope(), mockk(), dataStore)
val homeStore = spyk(
HomeFragmentStore(
Expand All @@ -117,10 +124,13 @@ class PocketUpdatesMiddlewareTest {
}

@Test
@Suppress("UNCHECKED_CAST")
fun `WHEN DeselectPocketStoriesCategory is dispatched THEN persist details in DataStore`() {
val categ1 = PocketRecommendedStoriesCategory("categ1")
val categ2 = PocketRecommendedStoriesCategory("categ2")
val dataStore: DataStore<SelectedPocketStoriesCategories> = mockk(relaxed = true)
val dataStore: DataStore<SelectedPocketStoriesCategories> =
mockk<FakeDataStore<SelectedPocketStoriesCategories>>(relaxed = true) as
DataStore<SelectedPocketStoriesCategories>
val pocketMiddleware = PocketUpdatesMiddleware(TestCoroutineScope(), mockk(), dataStore)
val homeStore = spyk(
HomeFragmentStore(
Expand All @@ -138,8 +148,11 @@ class PocketUpdatesMiddlewareTest {
}

@Test
@Suppress("UNCHECKED_CAST")
fun `WHEN persistCategories is called THEN update dataStore`() {
val dataStore: DataStore<SelectedPocketStoriesCategories> = mockk(relaxed = true)
val dataStore: DataStore<SelectedPocketStoriesCategories> =
mockk<FakeDataStore<SelectedPocketStoriesCategories>>(relaxed = true) as
DataStore<SelectedPocketStoriesCategories>

persistSelectedCategories(TestCoroutineScope(), listOf(mockk(relaxed = true)), dataStore)

Expand All @@ -148,6 +161,7 @@ class PocketUpdatesMiddlewareTest {
}

@Test
@Suppress("UNCHECKED_CAST")
fun `WHEN restoreSelectedCategories is called THEN dispatch PocketStoriesCategoriesSelectionsChange with data read from the persistence layer`() {
val persistedSelectedCategory: SelectedPocketStoriesCategory = mockk {
every { name } returns "testCategory"
Expand All @@ -156,9 +170,10 @@ class PocketUpdatesMiddlewareTest {
val persistedSelectedCategories: SelectedPocketStoriesCategories = mockk {
every { valuesList } returns mutableListOf(persistedSelectedCategory)
}
val dataStore: DataStore<SelectedPocketStoriesCategories> = mockk {
every { data } returns flowOf(persistedSelectedCategories)
}
val dataStore: DataStore<SelectedPocketStoriesCategories> =
mockk<FakeDataStore<SelectedPocketStoriesCategories>>(relaxed = true) {
every { data } returns flowOf(persistedSelectedCategories)
} as DataStore<SelectedPocketStoriesCategories>
val currentCategories = listOf(mockk<PocketRecommendedStoriesCategory>())
val homeStore = spyk(
HomeFragmentStore(HomeFragmentState())
Expand All @@ -183,3 +198,18 @@ class PocketUpdatesMiddlewareTest {
}
}
}

/**
* Incomplete fake of a [DataStore].
* Respects the [DataStore] contract with basic method implementations but needs to have mocked behavior
* for more complex interactions.
* Can be used as a replacement for mocks of the [DataStore] interface which might fail intermittently.
*/
private class FakeDataStore<T> : DataStore<T?> {
override val data: Flow<T?>
get() = flow { }

override suspend fun updateData(transform: suspend (t: T?) -> T?): T? {
return transform(null)
}
}

0 comments on commit 0cba75c

Please sign in to comment.