Skip to content

Builder<T>.single() throws wrong exception when used inside and{ ... } #203

@MartinHaeusler

Description

@MartinHaeusler

Hi,

I use strikt quite extensively by now, and I noticed that the single() assertion sometimes does not produce an assertion error, but rather an IllegalArgumentException. The test will fail either way (that's fine), but from the resulting error message it's hard to tell WHAT exactly failed.

Here's a minimal self-contained example which will produce an IllegalArgumentException, but should actually produce an assertion error (with the usual nice strikt messages):

class StriktTest {

    @Test
    fun striktTest(){
        class Person(val firstName: String, val hobbies: List<String>)

        // imagine that "p" is coming from some API call and needs to be nullable
        val p: Person? = Person("John", listOf("a","b"))

        expectThat(p).isNotNull().and {
            get { firstName }.isEqualTo("John")
            get { hobbies }.single().isA<String>().isEqualTo("a")
        }
    }
}

Here's the relevant portion of the stack trace I'm getting:

java.lang.IllegalArgumentException: List has more than one element.

	at kotlin.collections.CollectionsKt___CollectionsKt.single(_Collections.kt:519)
	at kotlin.collections.CollectionsKt___CollectionsKt.single(_Collections.kt:499)
	at strikt.assertions.IterableKt$single$2.invoke(Iterable.kt:29)
	at strikt.assertions.IterableKt$single$2.invoke(Iterable.kt)
	at strikt.internal.AssertionBuilder.get(AssertionBuilder.kt:92)
	at strikt.assertions.IterableKt.single(Iterable.kt:29)
	at org.example.test.StriktTest$striktTest$1.invoke(StriktTest.kt:21)
	at org.example.test.StriktTest$striktTest$1.invoke(StriktTest.kt:10)
	at strikt.internal.AssertionBuilder.and(AssertionBuilder.kt:37)

As you can see, it's hard to tell what went wrong, especially if there are multiple .single() assertions in a compound expectThat(...). I tried to look deeper into the issue, but I'm too unfamiliar with the internal context handling to make real sense of it right now. All I know is: it only seems to happen if single() is used inside an and { ... } clause.

Metadata

Metadata

Assignees

No one assigned

    Labels

    🐛 bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions