Skip to content

Instantly share code, notes, and snippets.

@diefferson
Last active March 13, 2020 14:15
Show Gist options
  • Select an option

  • Save diefferson/f0064b25cd33388e7c5175aa0f2904f1 to your computer and use it in GitHub Desktop.

Select an option

Save diefferson/f0064b25cd33388e7c5175aa0f2904f1 to your computer and use it in GitHub Desktop.
CoroutinesTest
abstract class BaseInteractorTest : KoinTest {
@CallSuper
@Before
open fun setup(){
Dispatchers.setMain(Dispatchers.Unconfined)
startKoin { modules(domainModules()) }
//declareMock<ErrorHandler>()
}
@CallSuper
@After
open fun finish(){
Dispatchers.resetMain()
stopKoin()
}
}
class GetBankTest : BaseInteractorTest() {
lateinit var interactor: GetBank
val repository: TransferRepository = mock()
@Before
override fun setup() {
super.setup()
interactor = GetBank(repository)
}
@Test
fun `Get bank case should call correct repository method`() = runBlockingTest {
val params = GetBank.Params("260")
whenever(repository.getBanks()).doReturn(listOf(Bank(code = "233"),Bank(code = "245"),Bank(code = "260")))
val bank = interactor.run(params)
verify(repository).getBanks()
assertThat(bank.code).isEqualTo("260")
}
}
class ResultAsync<T> private constructor(
scope: CoroutineScope, action: suspend () -> T):KoinComponent {
var onSuccess : (T) -> Unit = {}
var onError : (e: JunoException) -> Unit = {}
var onStatusChange : (status: AsyncStatus) -> Unit = {}
private val errorHandler by inject<ErrorHandler>()
companion object {
fun <T> with( scope: CoroutineScope, action: suspend () -> T) : ResultAsync<T> {
return ResultAsync(scope, action)
}
}
init {
scope.launch {
withContext(Dispatchers.Main) { onStatusChange(AsyncStatus.RUNNING) }
try {
val result = action()
withContext(Dispatchers.Main){
onStatusChange(AsyncStatus.DONE)
onSuccess(result)
}
}catch (e:Throwable){
withContext(Dispatchers.Main){
onStatusChange(AsyncStatus.ERROR)
onError(errorHandler.handler(e))
}
}
}
}
}
fun <T> ResultAsync<T>.onFailure(action: (exception: JunoException) -> Unit): ResultAsync<T> {
this.onError = action
return this
}
fun <T> ResultAsync<T>.onSuccess(action: (value: T) -> Unit): ResultAsync<T> {
this.onSuccess = action
return this
}
fun <T> ResultAsync<T>.onStatusChange(action: (AsyncStatus) -> Unit): ResultAsync<T> {
this.onStatusChange = action
return this
}
fun <T> CoroutineScope.asyncCatching( action: suspend () -> T): ResultAsync<T> {
return ResultAsync.with( this,action)
}
/**
* Abstract class for a UseCase
*/
abstract class UseCase<Type, in Params> where Type : Any? {
abstract suspend fun run(params: Params): Type
operator fun invoke(scope: CoroutineScope, params: Params) = scope.asyncCatching {
run(params)
}
@Suppress("UNCHECKED_CAST")
operator fun invoke(scope: CoroutineScope) = scope.asyncCatching {
run(None() as Params)
}
class None
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment