assertk
assertk copied to clipboard
`exactly` works incorrectly with multiple assertions
exactly assertion for collections works incorrectly when multiple assertions are provided in the assertion block.
Minimal failing scenario:
// snippet #1
@Test
fun test() {
val c = listOf(1, -1, 3)
assertThat(c).exactly(times = 1) {
it.isNegative()
it.isNegative()
}
}
Expected: success
got:
expected to pass exactly 1 times (4 failures)
org.opentest4j.AssertionFailedError: expected [[0]] to be negative but was:<1> ([1, -1, 3])
org.opentest4j.AssertionFailedError: expected [[0]] to be negative but was:<1> ([1, -1, 3])
org.opentest4j.AssertionFailedError: expected [[2]] to be negative but was:<3> ([1, -1, 3])
org.opentest4j.AssertionFailedError: expected [[2]] to be negative but was:<3> ([1, -1, 3])
org.gradle.internal.exceptions.DefaultMultiCauseException: expected to pass exactly 1 times (4 failures)
org.opentest4j.AssertionFailedError: expected [[0]] to be negative but was:<1> ([1, -1, 3])
org.opentest4j.AssertionFailedError: expected [[0]] to be negative but was:<1> ([1, -1, 3])
org.opentest4j.AssertionFailedError: expected [[2]] to be negative but was:<3> ([1, -1, 3])
org.opentest4j.AssertionFailedError: expected [[2]] to be negative but was:<3> ([1, -1, 3])
The snippet below passes as expected:
// snippet #2
@Test
fun test() {
val c = listOf(1, -1, 3)
assertThat(c).exactly(times = 1) {
it.isNegative()
}
}
Obvioulsy snippet #1 is not a real world scenario, but multiple assertions inexactly are useful - for example if we had isEven() extension method:
assertThat(c).exactly(times = 1) {
it.isNegative()
it.isEven()
}
Or if we wanted to check just two fields out of many in an object:
assertThat(c).exactly(times = 1) {
it.transform { it.country }
.isEqualTo(UKRAINE)
it.transform { it.city }
.isEqualTo(KYIV)
}