I am trying to unit test the kotlin coroutines. My project is following MVP pattern where the coroutines are used in the presenter like this:
fun authenticateWithUserAndPassword(usernameOrEmail: String, password: String) {
launchUI(strategy) {
view.showLoading()
try {
val token = retryIO("login") {
when {
settings.isLdapAuthenticationEnabled() ->
client.loginWithLdap(usernameOrEmail, password)
usernameOrEmail.isEmail() ->
client.loginWithEmail(usernameOrEmail, password)
else ->
client.login(usernameOrEmail, password)
}
}
val myself = retryIO("me()") { client.me() }
myself.username?.let { username ->
val user = User(
id = myself.id,
roles = myself.roles,
status = myself.status,
name = myself.name,
emails = myself.emails?.map { Email(it.address ?: "", it.verified) },
username = username,
utcOffset = myself.utcOffset
)
localRepository.saveCurrentUser(currentServer, user)
saveCurrentServer.save(currentServer)
localRepository.save(LocalRepository.CURRENT_USERNAME_KEY, username)
saveAccount(username)
saveToken(token)
analyticsManager.logLogin(
AuthenticationEvent.AuthenticationWithUserAndPassword,
true
)
view.saveSmartLockCredentials(usernameOrEmail, password)
navigator.toChatList()
}
} catch (exception: RocketChatException) {
when (exception) {
is RocketChatTwoFactorException -> {
navigator.toTwoFA(usernameOrEmail, password)
}
else -> {
analyticsManager.logLogin(
AuthenticationEvent.AuthenticationWithUserAndPassword,
false
)
exception.message?.let {
view.showMessage(it)
}.ifNull {
view.showGenericErrorMessage()
}
}
}
} finally {
view.hideLoading()
}
}
}
Here launchUI is defined as
/**
* Launches a coroutine on the UI context.
*
* @param strategy a CancelStrategy for canceling the coroutine job
*/
fun launchUI(strategy: CancelStrategy, block: suspend CoroutineScope.() -> Unit): Job =
MainScope().launch(context = strategy.jobs, block = block)
CancelStrategy class
class CancelStrategy(owner: LifecycleOwner, val jobs: Job) : LifecycleObserver {
init {
owner.lifecycle.addObserver(this)
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroy() {
jobs.cancel()
}
}
I am new to coroutine unit testing and tried writing a basic unit test
@Test
fun check_authentication_of_user() = runBlocking {
loginPresenter.authenticateWithUserAndPassword(USERNAME, PASSWORD)
verify(navigator).toChatList()
}
On running the test I am getting the following error.
java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlinx.coroutines.BuildersKt__Builders_commonKt.launch, parameter context
Any help regarding how to unit test the given method will be appreciated.