
Exercise: Flow testing
Test the observeAppointments function from the ObserveAppointmentsUseCase class. Starting code:
class ObserveAppointmentsUseCase( private val appointmentRepository: AppointmentRepository ) { fun observeAppointments(): Flow<List<Appointment>> = appointmentRepository .observeAppointments() .filterIsInstance<AppointmentUpdate>() .map { it.appointments } .distinctUntilChanged() .retry { it is ApiException && it.code in 500..599 } } interface AppointmentRepository { fun observeAppointments(): Flow<AppointmentEvent> } sealed class AppointmentEvent data class AppointmentUpdate( val appointments: List<Appointment> ) : AppointmentEvent() data object AppointmentConfirmed : AppointmentEvent() data class Appointment(val title: String, val time: Instant) data class ApiException(val code: Int) : Throwable()
You should test the following cases:
- should receive only appointment lists from appointment updates
- should not receive non-distinct values
- should retry exceptions of type
ApiExceptionwith code 5XX
This problem can either be solved in the below playground or you can clone kotlin-exercises project and solve it locally. In the project, you can find code template for this exercise in coroutines/flow/ObserveAppointmentsUseCase.kt. You can find there starting code.
Playground
import kotlinx.coroutines.flow.* import java.time.Instant class ObserveAppointmentsUseCase( private val appointmentRepository: AppointmentRepository ) { fun observeAppointments(): Flow<List<Appointment>> = appointmentRepository .observeAppointments() .filterIsInstance<AppointmentUpdate>() .map { it.appointments } .distinctUntilChanged() .retry { it is ApiException && it.code in 500..599 } } interface AppointmentRepository { fun observeAppointments(): Flow<AppointmentEvent> } sealed class AppointmentEvent data class AppointmentUpdate( val appointments: List<Appointment> ) : AppointmentEvent() data object AppointmentConfirmed : AppointmentEvent() data class Appointment(val title: String, val time: Instant) data class ApiException(val code: Int) : Throwable()