Sean Keane
05/01/2020, 4:11 PMLogin
but it calls the function and kicks it off on a new Coroutine. This causes the test to continue and hit the verify BEFORE the request is made. Im working in Multiplatform and using Coroutine testing tools in Android as a target for the tests. This is my test:
class KAuthenticationServiceTest {
var loginRequest = service.auth.login.build("<mailto:fakeEmail@mail.com|fakeEmail@mail.com>", "fakePassword")
var mockStorage = MockStorage()
var mockCredentialsManager = MockCredentialsManager()
var mockNetworkManager = MockNetworkManager()
lateinit var authService: AuthService
@BeforeTest
fun setup() {
authService = KAuthenticationService(
storage = mockStorage,
credentialsManager = mockCredentialsManager,
networkManager = mockNetworkManager
)
}
/**
* Given: A user requests to login
* When: The call is made to the login interactor
* Then: The request is executed successfully
*/
@Test
fun callIsMadeToLoginInteractorToExecuteRequest() = runTest {
authService.login(loginRequest, {}, {})
assertTrue {
mockNetworkManager.requestValue == loginRequest
}
}
}
The run test function in Android is the following:
val mainThreadSurrogate = newSingleThreadContext("UI thread")
actual fun <T> runTest(block: suspend () -> T) {
Dispatchers.setMain(mainThreadSurrogate)
runBlockingTest { block() }
}
Im a bit lost as to how I can get the runBlocking to run the authService.login on the same thread so it blocks until executed and then continues to the assert? Has anyone got any suggestions?Luis Munoz
05/01/2020, 8:47 PMSean Keane
05/01/2020, 8:51 PMinternal class LoginInteractor(
private val loginRequest: LoginRequest,
private val onSuccess: (Unit) -> Unit,
private val onError: (KarhooError) -> Unit,
context: CoroutineContext = Dispatchers.Main,
private val credentialsManager: CredentialsManager,
private val networkManager: NetworkManager
) :
BaseCallInteractor<Credentials>(
requestRequiresToken = false,
context = context,
credentialsManager = credentialsManager,
onError = onError
) {
override suspend fun makeRequest() {
networkManager.request(loginRequest).fold(onError, ::onSuccess)
}
private fun onSuccess(credentials: Credentials) {
credentialsManager.saveCredentials(credentials)
onSuccess.invoke(Unit)
}
}
internal abstract class BaseCallInteractor<RESPONSE> protected constructor(private val requestRequiresToken: Boolean,
private val credentialsManager: CredentialsManager,
private val onError: (KError) -> Unit,
private val context: CoroutineContext,
) {
internal abstract suspend fun makeRequest()
fun execute() {
GlobalScope.launch(context) {
// TODO CHECK IF TOKEN IS EXPIRED
if (shouldRefreshToken()) {
} else {
makeRequest()
}
}
}
private fun shouldRefreshToken(): Boolean {
//requestRequiresToken && !credentialsManager.isValidToken
return false
}
private suspend fun successfulCredentials(credentials: Credentials) {
credentialsManager.saveCredentials(credentials)
makeRequest()
}
}
Luis Munoz
05/01/2020, 8:58 PMSean Keane
05/01/2020, 9:02 PM