https://kotlinlang.org logo
#getting-started
Title
# getting-started
m

Mendess

11/15/2021, 12:10 PM
How do I know if a lateinit local variable is initialized?
Copy code
fun foo() {
    lateinit var x: Int
    if (::x.isInitialized()) {}
}
This doesn't seem to work
j

Joffrey

11/15/2021, 12:11 PM
lateinit var
probably shouldn't be used in this case, probably nullability would work better. What is your exact use case here?
m

Mendess

11/15/2021, 12:13 PM
async unit tests, I pass a callback to an async method and I want to check if this async method has initialized my variable
Copy code
@Test
fun foo() {
  lateinit var x: Int
  someAsyncComputation { x = it }
  GlobalScope.launch {
    while (!::x.isInitialized()) { deplay(1000) }
    // do somthing with x
  }
}
I know it's kinda hackish but I think it's good enough for tests
j

Joffrey

11/15/2021, 12:15 PM
Why not simply use null as initial value and check for null?
lateinit
is designed for avoiding null checks when you know better than the compiler that your variable will be initialized in due time. Here you really don't know (you have to manually check), so why not just use nulls?
m

Mendess

11/15/2021, 12:17 PM
because it won't do smart casting to non null I think and I'll have to use
!!
I wanted to avoid that but I'll do it with null if I don't have a choice
j

Joffrey

11/15/2021, 12:18 PM
Also, for this specific use case there are most likely much better approaches than polling. The current approach makes the test slow. Also, doing things in
GlobalScope
might mess up error handling of the test framework, because you're not waiting for this coroutine to finish
because it won't do smart casting to non null I think and I'll have to use 
!!
You can also store the asserted result in another local non-null
val
inside the
launch
, but honestly I believe you should just change the approach here. For instance, an alternative is to use a `CompletableDeferred`:
Copy code
val x = CompletableDeferred<Int>()
  someAsyncComputation { x.complete(42) }
  GlobalScope.launch {
    val completedX = x.await()
    // do somthing with completedX
  }
This still doesn't solve the
GlobalScope
problem, but at least you don't have this weird polling anymore.
h

hfhbd

11/15/2021, 12:36 PM
or "just" make the test async and use
suspendContinutation
j

Joffrey

11/15/2021, 12:37 PM
If the project is JVM only you could use
runBlockingTest
from kotlinx-coroutines-test
And
someAsyncComputation
could be made a
suspend
function instead of callback-based
m

Mendess

11/15/2021, 12:41 PM
thanks for all this feedback! I have gotten rid of global scope and restructured the test in general
will look into these options too
s

smit01

11/15/2021, 5:58 PM
Is primitive lateinit property is allowed in kotlin?
106 Views