What is special about assertNotNull's return value compared with assertTrue(x != null)?
answer
- assertNotNull RETURNS the non-null value
- contract enables smart-cast
- no !! / ?. needed after
- assertTrue(x!=null) only checks, no narrowing
- assertNull is the mirror
basics
~20 sassertNotNull both checks the value isn't null and gives you back the value as a non-null type. After it, you can use the value without ?. or !!. assertTrue(x != null) only checks; it doesn't unwrap the type.
solid answer
~40 s`assertNotNull(actual, message?)` is declared `fun <T : Any> assertNotNull(actual: T?, message: String? = null): T` — it returns the value as the **non-null** type `T`, and a `contract` lets the original variable smart-cast. So after `val s = assertNotNull(maybe)` (or even just `assertNotNull(maybe)`), the compiler treats it as non-null and you can call members directly without `!!` or `?.`. `assertTrue(x != null)` only checks a boolean — it neither narrows the type nor unwraps, and produces a worse message (`expected true`). The mirror function `assertNull` fails unless the value is `null`. Preferring `assertNotNull` makes the rest of the test type-safe and self-documenting.
code
kotlin · 8 linesimport kotlin.test.assertNotNull
val name: String? = repo.findName(id)
val nn: String = assertNotNull(name) // returns non-null
println(nn.length) // safe
assertNotNull(name)
println(name.length) // smart-cast, no ?.go deeper
Knows assertNotNull fails on null and assertNull fails on non-null.
Explains that assertNotNull returns the unwrapped non-null value and enables smart-cast, avoiding !!.
Names the contract/generic signature <T:Any>(T?): T and contrasts message quality vs assertTrue.
Advocates assertNotNull as a readability/type-safety convention and discusses how contracts propagate through the test for safer dereferencing.
## Null assertions and smart-cast benefit - `assertNull(actual, message?)` fails unless `actual` is `null`. - `assertNotNull(actual, message?)` fails unless `actual` is non-null. ### The key behavior: `assertNotNull` returns the unwrapped value `assertNotNull` is declared to **return** the value as a non-null type. Its signature is roughly `fun <T : Any> assertNotNull(actual: T?, message: String? = null): T`. After the call the compiler knows the value is non-null — either by using the returned value, or via a `contract` so the original variable smart-casts. ```kotlin import kotlin.test.assertNotNull import kotlin.test.assertNull val name: String? = repo.findName(id) // Option A: use the returned non-null value val nonNull: String = assertNotNull(name) println(nonNull.length) // no ?. needed // Option B: contract lets the original var smart-cast assertNotNull(name) println(name.length) // 'name' is now String, not String? assertNull(repo.findName(missingId)) ``` This is why `assertNotNull` is preferred over `assertTrue(x != null)`: it both asserts *and* narrows the type so the rest of the test can dereference safely without `!!` or `?.`.
- How does the original variable become non-null without reassigning it?assertNotNull declares a Kotlin `contract` (returnsNotNull / implies non-null), so the compiler smart-casts the variable in the following code.
- What's the downside of assertTrue(x != null)?It doesn't narrow the type (you still need !!/?.) and the failure message is just 'expected true' instead of naming the null value.
saying these in an interview costs you the question
- Says assertNotNull returns Unit/Boolean
- Uses !! after assertNotNull instead of the returned value
- Claims assertTrue(x != null) smart-casts
- Confuses assertNull and assertNotNull
- Thinks you must reassign to get a non-null var