For #21733 - Replace mock of an interface with mock of a fake. (backport #21766) (#22326)

* For #21733 - Replace mock of an interface with mock of a fake.

(cherry picked from commit 4d5bd9eca4)

* For #21733 - Simplify test to not depend on store updates.

(cherry picked from commit 79a4873843)

Co-authored-by: Mugurell <Mugurell@users.noreply.github.com>
pull/415/head
mergify[bot] 3 years ago committed by GitHub
parent a5540a0b31
commit 8ee2acbcdf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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
@ -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"
@ -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(
@ -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(
@ -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(
@ -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)
@ -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"
@ -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())
@ -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)
}
}

@ -39,15 +39,10 @@ class DefaultPocketStoriesControllerTest {
)
val controller = DefaultPocketStoriesController(mockk(), store, mockk(), metrics)
controller.handleCategoryClick(category1)
verify(exactly = 0) { store.dispatch(HomeFragmentAction.DeselectPocketStoriesCategory(category1.name)) }
verify { store.dispatch(HomeFragmentAction.SelectPocketStoriesCategory(category1.name)) }
verify { metrics.track(Event.PocketHomeRecsCategoryClicked(category1.name, 1, true)) }
controller.handleCategoryClick(category2)
verify(exactly = 0) { store.dispatch(HomeFragmentAction.SelectPocketStoriesCategory(category2.name)) }
verify { store.dispatch(HomeFragmentAction.DeselectPocketStoriesCategory(category2.name)) }
verify { metrics.track(Event.PocketHomeRecsCategoryClicked(category2.name, 2, false)) }
verify { metrics.track(Event.PocketHomeRecsCategoryClicked(category2.name, 1, false)) }
}
@Test

Loading…
Cancel
Save