I am trying to write some UnitTests for my native mobile applications, but have ran into a roadblock in my Android Tests. Specifically, I am struggling to find an example of Kotlin's version of Swift's Expectations/Promises..
I've found examples of Kotlin Promises, but they seem to be way more complicated than needed...
For example, here is a test for the login API function in my iOS project:
func testLogin() {
/// Prepare for login
if CURRENT_USER != nil {
logout()
}
/// Login
let promise = expectation(description: "User is logged in.")
// 1. Given
var isSuccess: Bool = false
// 2. When
User.login(username: maleUsername, password: malePassword, success: {
isSuccess = true
promise.fulfill()
}) { (_, agreeToTerms) in
XCTFail()
}
wait(for: [promise], timeout: maxTimeOut)
// 3. Then
XCTAssertNotNil(CURRENT_USER)
XCTAssertTrue(isSuccess)
/// Logout
logout()
}
This is pretty simple to me. I have an asynchronous method login
that has two possible completion blocks: success
and failure
; and I need to wait for one of them to complete before evaluating. To do this, I create a promise before the call, then I fulfill the promise in the two completion blocks, and I wait for the promise to fulfill before running my assertions.
Now in Kotlin, I have a similar test:
private val loginFragment = LoginFragment()
@Test
fun loginTest() {
val username = ""
val password = ""
// TODO: Create Promise
loginFragment.loginViewModel
.login(username, password)
.observe(loginFragment, Observer {
loginFragment.activity?.onResult(it?.result,
onSuccess = {
// TODO: Fill Promise
},
onValidationError = {
// TODO: Fail Test
})
})
// TODO: Assertions
}
But I can't find an equivalent of swift's promises..
Does one exist in Kotlin? If not, how would I implement a version of my Swift's testLogin
method in Kotlin?
You can use Kotlin coroutines, for example:
@Test
fun loginTest() {
val result = runBlocking {
val loginResult = login()
loginResult
}
if (result == "Success") {
// do your work when Success
} else {
// do your work when Error
}
}
suspend fun login(): String = suspendCoroutine { continuation ->
val username = ""
val password = ""
loginFragment.loginViewModel
.login(username, password)
.observe(loginFragment, Observer {
loginFragment.activity?.onResult(it?.result,
onSuccess = {
continuation.resume("Success")
},
onValidationError = {
continuation.resume("Error") // take a look for other methods, e.g. resumeWithException(exception)
})
})
}
To use coroutines you need to add next lines to app's build.gradle file dependencies:
final KOTLIN_COROUTINES_VERSION = '1.0.1' implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$KOTLIN_COROUTINES_VERSION"
Hope it will help.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With