Hello all, I have a question about a specific asse...
# kotest
d
Hello all, I have a question about a specific assertion, if you use:
Copy code
thing.shouldBeNull()
And
thing
is not null, you get a weird error in IntelliJ:
Copy code
org.opentest4j.AssertionFailedError: Expected value to be null, but was thing.
Expected :null
Actual   :null
Actual here should be able to reuse
thing
instead of just
null
. I traced this back to
InvokeMatcher.kt
where for this case a builder without expected / actual value is created:
Copy code
AssertionErrorBuilder.create().withMessage(result.failureMessage()).build()
And it gets there because the Matcher for
beNull
is a simple matcher that it doesn't support
Copy code
fun beNull() = object : Matcher<Any?> {

  override fun test(value: Any?): MatcherResult {
    val passed = value == null

     return MatcherResult.invoke(
        passed,
        { "Expected value to be null, but was $value." },
        { "Expected value to not be null, but was null." }
     )
  }
}
If I replace this implementation with:
Copy code
object : Matcher<Any?> {
                    override fun test(value: Any?): ComparisonMatcherResult {
                        val passed = value == null

                        return ComparisonMatcherResult(
                            passed,
                            value.print(),
                            null.print(),
                            { "Expected value to be null, but was $value." },
                            { "Expected value to not be null, but was null." },
                        )
                    }
                }
I get a nicer message where the actual is properly filled with the real value
Maybe this could be an improvement
💯 1
a
👀
you have not created an issue yet, right?
can you help me reproduce, as I don't see this issue happening:
Copy code
import io.kotest.core.spec.style.StringSpec
import io.kotest.matchers.nulls.shouldBeNull

class ShouldBeNullTest: StringSpec() {
   init {
       "should fail with expected message" {
          val notNullThing = "NotNullThing"
          notNullThing.shouldBeNull()
       }
   }
}
Expected value to be null, but was NotNullThing.
d
It's not about the message, but IntelliJ shows a line with the expected and actual in its output and you can click it to have like a diff
So, like this:
Copy code
org.opentest4j.AssertionFailedError: Expected value to be null, but was thing.
Expected :null
Actual   :null
This is the console output in IntelliJ
"Actual: null" does not seem correct, as it was not null, and this is caused by the matcher result not having that properties bound
a
can you share a complete repro, like I did? because I've pasted the output from Intellij as well
and the versions of both Intellij and the plugin
d
Ah I think I understand what is happening, this happens when you use Kotest assertions, but use JUnit 5 style tests, then you get the lines which show the expected and actual
So like this:
Copy code
import io.kotest.matchers.nulls.shouldBeNull
import org.junit.jupiter.api.Test

class ShouldBeNullTest {
    @Test
    fun `should fail with expected message`() {
        val notNullThing = "NotNullThing"
        notNullThing.shouldBeNull()
    }
}
Then the output is:
Copy code
org.opentest4j.AssertionFailedError: Expected value to be null, but was NotNullThing.
Expected :null
Actual   :null
<Click to see difference>
You have a clickable link with "click to see difference" and that is now very weird, because if you click on it , you just get a diff of 2 null values
It's not just this assertion I discovered, a lot of assertions have this issue if you use JUnit to run them