:wave: I found a problem when doing an assertion o...
# kotest
p
👋 I found a problem when doing an assertion on a nullable variable e.g.
Copy code
nullableThing?.shouldBe(something)  // This works
nullableThing?.shouldBeGreaterThan(something). // This doesn't work
If nullableThing is null the safe call stops the assertion from being called, so the tests passes when it shouldn’t. I found two ways to fix this but neither seem ideal to me: • Add another assertion to check that the thing isn’t null e.g.
nullableThing shouldNotBe null
• Use
!!.
instead of
?.
but this gives a null pointer exception when the test fails which could lead to confusion Is there a better way to deal with assertions on nullable variables?
c
Copy code
val x: String? = "blah"
x.shouldNotBeNull()
x.shouldBe("blah")
ok thats basically option one from your question. i would recommend to do it like that
w
Isn’t
nullableThing?.something()
basically impossible to override? It’s compiler that is not calling
something
because that’s how
?.
operator works blob thinking upside down
c
yes, nullableThing?. does nothing when nullableThing is null so theres nothing to override. but you can override Any?.something then you can do nullableThing.something()
r
You can use
shouldBe
on a nullable type. Just use
nullableThing.shouldBe(something)
.
This works as expected for me:
Copy code
val nullableThing: String? = null
nullableThing.shouldBe("not null")
Copy code
Expected "not null" but actual was null
java.lang.AssertionError: Expected "not null" but actual was null
p
Thanks I’ll give that a try
Sorry I caused some confusion by simplifying my example code too much, the matcher I was trying to use was
shouldBeGreaterThan
shouldBe
and
shouldNotBe
work with nullable variables but
shouldBeGreaterThan
doesn’t, that causes this error -
Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type Int?
Is there a reason why only certain matchers can handle nullables or is this something that could be added to other matchers?
c
it just makes no sense to check if null is greater than 10. its neither greater nor lower than 10. but it makes sense to check it for equality. its not equal to anything except null
1
so for things that make no sense to do with null you first assert that they are not null
p
I see what you mean, although I’d argue that null is not greater than anything so that matcher could be altered to handle null and then it would give an error such as
null should be > 0
The danger with the way it currently works is that it’s too easy to try to fix the problem by using
?.
and then you have a test that will incorrectly pass when the variable is null
Here’s a similar thread where I tried to do this with strings - https://kotlinlang.slack.com/archives/CT0G9SD7Z/p1640084172325700
s
Some matchers work on nulls and some don't. If you find one that doesn't, but it should, then a PR is welcome to "fix" it. And a good workaround is that shouldNotBeNull() can be chained, so
Copy code
val name: String? = "foo"
name.shouldNotBeNull().shouldHaveLength(3)
most matchers should be chainable
👍 1
p
Cheers Sam, I’ve started chaining shouldNotBeNull in my tests, and will have a look at fixing this in Kotest at some point, will create an issue first
m
I have used a different style for potentially nullable things:
Copy code
nullableThing?.let {
    it shouldBe something
} ?: fail("thing should not be null")
👍 1