How do I know if a lateinit local variable is init...
# getting-started
m
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
lateinit var
probably shouldn't be used in this case, probably nullability would work better. What is your exact use case here?
m
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
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
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
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
or "just" make the test async and use
suspendContinutation
j
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
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
Is primitive lateinit property is allowed in kotlin?
165 Views