hi all, funny question but why did this function i...
# getting-started
a
hi all, funny question but why did this function i wrote work?
Copy code
inline fun <reified T: Throwable> assertThrows(clazz: KClass<T>, block: () -> Unit) {
    var exception: Throwable? = null
    try {
        block()
    } catch (e: Throwable) {
        exception = e
    } finally {
        assertTrue(exception is T)
    }
}
i used it expecting it to not work, but it successfully asserts T based on the clazz parameter i pass in, even though i dont actually use the clazz parameter in my function. is the runtime able to narrow down T based on the function parameter?
example
Copy code
assertThrows(NoSuchElementException::class) {
    dao.getContractAccount(session)
}
assertThrows(NoSuchElementException::class) {
    dao.getContractAccount(session)
}
assertThrows(IllegalStateException::class) {
    dao.getContractAccount(session)
}
first 2 pass, last call fails
r
Yep, that's exactly what
reified
does
In fact you can remove
clazz
parameter and call it like
Copy code
assertThrows<NoSuchElementException>() {
a
oh that makes sense
much better
i was so surprised at the inference coming from the fun parameter i stopped thinking about it 😛
oh of course, this is simply what happens when you define a value for a generic parameter, and the <Type> gets greyed out as its inferred from the definition itself
c
Note that this function is already in the standard kotlin.test library, IIRC it's called
assertFailsWith
or similar
a
ah ok, some searches didnt turn up anything useful and junit5's stuff wasnt so nice (wouldnt work with suspend funs)
a
oh my project doesnt have that dependency for some weird reason
appreciate it!
c
It's not added by default, which platforms are you targetting?
a
android, no i wasnt expecting it to be there by default but i work on a large and mature project
and would have expected someone else to have gotten around to this sooner (because of all the junk that is already present)
r
Most android projects start with junit and never add kotlin.test
They mostly overlap but I think it's fine to use both together
e
kotlin-test assertions have contacts and JUnit assertions don't, so in some ways kotlin-test is nicer to use, but except in multiplatform projects I tend to use JUnit assertions anyway because they're more complete and using both can be confusing