I'm trying to test the length of an integer array with hamcrest and <
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.collection.IsArrayWithSize.arrayWithSize
import org.hamcrest.core.IsEqual.equalTo
import org.hamcrest.core.Is.`is` as Is
…
val parts = intArrayOf(1, 2, 3)
assertThat(parts, arrayWithSize(3))
assertThat(parts, Is(arrayWithSize(3)))
assertThat(parts, Is(arrayWithSize(equalTo(3))))
As far as I understand all three asserts should work and the equivalent statements will work in Java. But they don't work with Kotlin:
[ERROR] …/Decomposed_Test.kt:[287,14] Type mismatch: inferred type is IntArray but String! was expected
[ERROR] …/Decomposed_Test.kt:[287,21] Type mismatch: inferred type is Matcher<Array<(???..???)>!>! but Boolean was expected
[ERROR] …/Decomposed_Test.kt:[288,14] Type mismatch: inferred type is IntArray but String! was expected
[ERROR] …/Decomposed_Test.kt:[288,21] Type mismatch: inferred type is Matcher<(???..???)>! but Boolean was expected
[ERROR] …/Decomposed_Test.kt:[289,14] Type mismatch: inferred type is IntArray but String! was expected
[ERROR] …/Decomposed_Test.kt:[289,21] Type mismatch: inferred type is Matcher<(???..???)>! but Boolean was expected
This is of course wrong as I'm not comparing strings. I tried adding some reasons to the assert to see of that helps:
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.collection.IsArrayWithSize.arrayWithSize
import org.hamcrest.core.IsEqual.equalTo
import org.hamcrest.core.Is.`is` as Is
…
val parts = intArrayOf(1, 2, 3)
assertThat(/* reason = */ "array has 3 elements", /* actual = */ parts, /* matcher = */ arrayWithSize(3))
assertThat(/* reason = */ "array has 3 elements", /* actual = */ parts, /* matcher = */ Is(arrayWithSize(3)))
assertThat(/* reason = */ "array has 3 elements", /* actual = */ parts, /* matcher = */ Is(arrayWithSize(equalTo(3))))
Different error message but still doesn't help:
[ERROR] …/Decomposed_Test.kt:[287,91] Type mismatch: inferred type is IntArray! but Array<(out) TypeVariable(E)!>! was expected
[ERROR] …/Decomposed_Test.kt:[288,91] Type mismatch: inferred type is IntArray! but Array<(out) TypeVariable(E)!>? was expected
[ERROR] …/Decomposed_Test.kt:[288,91] Type mismatch: inferred type is IntArray! but Array<(out) TypeVariable(E)!>! was expected
[ERROR] …/Decomposed_Test.kt:[288,94] Type mismatch: inferred type is Matcher<Array<(out) (???..???)>!>! but Matcher<IntArray!>! was expected
[ERROR] …/Decomposed_Test.kt:[289,91] Type mismatch: inferred type is IntArray! but Array<(out) TypeVariable(E)!>? was expected
[ERROR] …/Decomposed_Test.kt:[289,91] Type mismatch: inferred type is IntArray! but Array<(out) TypeVariable(E)!>! was expected
[ERROR] …/Decomposed_Test.kt:[289,94] Type mismatch: inferred type is Matcher<Array<(out) (???..???)>!>! but Matcher<IntArray!>! was expected
Why is that?
PS: I'm not interested in suggestions of alternate frameworks.
Answering my own question (as I often do) the correct code is:
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.collection.IsArrayWithSize.arrayWithSize
import org.hamcrest.core.IsEqual.equalTo
import org.hamcrest.core.Is.`is` as Is
…
val parts = intArrayOf(1, 2, 3)
assertThat(/* actual = */ parts.toTypedArray(), /* matcher = */ arrayWithSize(3))
assertThat(/* actual = */ parts.toTypedArray(), /* matcher = */ Is(arrayWithSize(3)))
assertThat(/* actual = */ parts.toTypedArray(), /* matcher = */ Is(arrayWithSize(equalTo(3))))
That conversion is quite the performance killer but in a unit test I don't care. If I ever come around to converting the main source from java to kotlin stuff like this might hurt.