fjoglar
10/19/2023, 9:50 PM@OptIn(ExperimentalCoroutinesApi::class)
class EventRepositoryTest {
    private val eventService = EventServiceStub()
    private val eventCache = EventCacheStub()
    private val eventRepository = EventRepository(
        localCache = eventCache,
        remoteService = eventService,
    )
    @Test
    fun test_deliversRemoteEvents_onNonValidCache() = runTest {
        val remoteEvents = makeEvents(1)
        val receivedEvents = mutableListOf<List<Event>>()
        backgroundScope.launch(UnconfinedTestDispatcher()) {
            eventRepository.load(anyFilter().toList(receivedEvents)
        }
        eventService.succeedsWithEvents(remoteEvents)
        eventCache.failsWithNonValidCache()
        assertEquals(remoteEvents, receivedEvents.first())
    }
    // region Helpers
    private class EventServiceStub : EventService {
        private var result: Result<List<Event>>? = null
        override suspend fun load(filter: EventFilter): Result<List<Event>> {
            return result!!
        }
        fun succeedsWithEvents(remoteEvents: List<Event>) {
            result = Result.success(remoteEvents)
        }
    }
    private class EventCacheStub : EventCache {
        private val flow = MutableSharedFlow<List<Event>?>()
        override fun load(filter: EventFilter): Flow<List<Event>?> = flow
        suspend fun succeedsWithEvents(events: List<Event>?) {
            flow.emit(events)
        }
        suspend fun failsWithNonValidCache() {
            flow.emit(null)
        }
        override suspend fun save(events: List<Event>, filter: EventFilter) {
            flow.emit(events)
        }
    }
    // endregion
}
Here I am expecting to receive remoteEvents when the localCache is not valid, which is when it returns null . Actually, EventCacheStub emits a null value when calling failsWithNonValidCache  but it does not emit nothing and completes after calling the save  method from the repository implementation.
Here is my repository implementation:
class EventRepository(
    private val localCache: EventCache,
    private val remoteService: EventService,
) : EventLoader {
    override fun load(filter: EventFilter): Flow<List<Event>> {
        return localCache.load(filter)
            .onEach {
                if (it == null) {
                    remoteService.load(filter).onSuccess { localCache.save(it, filter)}
                }
            }
            .filterNotNull()
    }
}
Thanks gratitude thank you