blob: 7e44ea799b3fe1b0f616103886b9dde7092e6f77 [file] [log] [blame]
/*
* Copyright 2015-2022 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
* accompanies this distribution and is available at
*
* https://www.eclipse.org/legal/epl-v20.html
*/
package org.junit.jupiter.api
import kotlinx.coroutines.runBlocking
import org.junit.jupiter.api.AssertionTestUtils.assertMessageEquals
import org.junit.jupiter.api.AssertionTestUtils.assertMessageStartsWith
import org.junit.jupiter.api.AssertionTestUtils.expectAssertionFailedError
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.DynamicContainer.dynamicContainer
import org.junit.jupiter.api.DynamicTest.dynamicTest
import org.opentest4j.AssertionFailedError
import org.opentest4j.MultipleFailuresError
import java.util.stream.Stream
import kotlin.reflect.KClass
/**
* Unit tests for JUnit Jupiter [org.junit.jupiter.api] top-level assertion functions.
*/
class KotlinAssertionsTests {
// Bonus: no null check tests as these get handled by the compiler!
@Test
fun `assertAll with functions that do not throw exceptions`() {
assertAll(Stream.of({ assertTrue(true) }, { assertFalse(false) }))
assertAll("heading", Stream.of({ assertTrue(true) }, { assertFalse(false) }))
assertAll(setOf({ assertTrue(true) }, { assertFalse(false) }))
assertAll("heading", setOf({ assertTrue(true) }, { assertFalse(false) }))
assertAll({ assertTrue(true) }, { assertFalse(false) })
assertAll("heading", { assertTrue(true) }, { assertFalse(false) })
}
@Test
fun `assertAll with functions that throw AssertionErrors`() {
val multipleFailuresError = assertThrows<MultipleFailuresError> {
assertAll(
{ assertFalse(true) },
{ assertFalse(true) }
)
}
assertExpectedExceptionTypes(multipleFailuresError, AssertionFailedError::class, AssertionFailedError::class)
}
@Test
fun `assertThrows and fail`() {
assertThrows<AssertionError> { fail("message") }
assertThrows<AssertionError> { fail("message", AssertionError()) }
assertThrows<AssertionError> { fail("message", null) }
assertThrows<AssertionError>("should fail") { fail({ "message" }) }
assertThrows<AssertionError>({ "should fail" }) { fail(AssertionError()) }
assertThrows<AssertionError>({ "should fail" }) { fail(null as Throwable?) }
}
@Test
fun `expected context exception testing`() = runBlocking<Unit> {
assertThrows<AssertionError>("Should fail async") {
suspend { fail("Should fail async") }()
}
}
@TestFactory
fun assertDoesNotThrow(): Stream<out DynamicNode> = Stream.of(
dynamicContainer(
"succeeds when no exception thrown",
Stream.of(
dynamicTest("for no arguments variant") {
val actual = assertDoesNotThrow { 1 }
assertEquals(1, actual)
},
dynamicTest("for no arguments variant (suspended)") {
runBlocking {
val actual = assertDoesNotThrow { suspend { 1 }() }
assertEquals(1, actual)
}
},
dynamicTest("for message variant") {
val actual = assertDoesNotThrow("message") { 2 }
assertEquals(2, actual)
},
dynamicTest("for message variant (suspended)") {
runBlocking {
val actual = assertDoesNotThrow("message") { suspend { 2 }() }
assertEquals(2, actual)
}
},
dynamicTest("for message supplier variant") {
val actual = assertDoesNotThrow({ "message" }) { 3 }
assertEquals(3, actual)
},
dynamicTest("for message supplier variant (suspended)") {
runBlocking {
val actual = assertDoesNotThrow({ "message" }) { suspend { 3 }() }
assertEquals(3, actual)
}
}
)
),
dynamicContainer(
"fails when an exception is thrown",
Stream.of(
dynamicTest("for no arguments variant") {
val exception = assertThrows<AssertionError> {
assertDoesNotThrow {
fail("fail")
}
}
assertMessageEquals(
exception,
"Unexpected exception thrown: org.opentest4j.AssertionFailedError: fail"
)
},
dynamicTest("for no arguments variant (suspended)") {
runBlocking {
val exception = assertThrows<AssertionError> {
assertDoesNotThrow {
suspend { fail("fail") }()
}
}
assertMessageEquals(
exception,
"Unexpected exception thrown: org.opentest4j.AssertionFailedError: fail"
)
}
},
dynamicTest("for message variant") {
val exception = assertThrows<AssertionError> {
assertDoesNotThrow("Does not throw") {
fail("fail")
}
}
assertMessageEquals(
exception,
"Does not throw ==> Unexpected exception thrown: org.opentest4j.AssertionFailedError: fail"
)
},
dynamicTest("for message variant (suspended)") {
runBlocking {
val exception = assertThrows<AssertionError> {
assertDoesNotThrow("Does not throw") {
suspend { fail("fail") }()
}
}
assertMessageEquals(
exception,
"Does not throw ==> Unexpected exception thrown: org.opentest4j.AssertionFailedError: fail"
)
}
},
dynamicTest("for message supplier variant") {
val exception = assertThrows<AssertionError> {
assertDoesNotThrow({ "Does not throw" }) {
fail("fail")
}
}
assertMessageEquals(
exception,
"Does not throw ==> Unexpected exception thrown: org.opentest4j.AssertionFailedError: fail"
)
},
dynamicTest("for message supplier variant (suspended)") {
runBlocking {
val exception = assertThrows<AssertionError> {
assertDoesNotThrow({ "Does not throw" }) {
suspend { fail("fail") }()
}
}
assertMessageEquals(
exception,
"Does not throw ==> Unexpected exception thrown: org.opentest4j.AssertionFailedError: fail"
)
}
}
)
)
)
@Test
fun `assertAll with stream of functions that throw AssertionErrors`() {
val multipleFailuresError = assertThrows<MultipleFailuresError>("Should have thrown multiple errors") {
assertAll(Stream.of({ assertFalse(true) }, { assertFalse(true) }))
}
assertExpectedExceptionTypes(multipleFailuresError, AssertionFailedError::class, AssertionFailedError::class)
}
@Test
fun `assertAll with collection of functions that throw AssertionErrors`() {
val multipleFailuresError = assertThrows<MultipleFailuresError>("Should have thrown multiple errors") {
assertAll(setOf({ assertFalse(true) }, { assertFalse(true) }))
}
assertExpectedExceptionTypes(multipleFailuresError, AssertionFailedError::class, AssertionFailedError::class)
}
@Test
fun `assertThrows with function that does not throw an exception`() {
val assertionMessage = "This will not throw an exception"
val error = assertThrows<AssertionFailedError>("assertThrows did not throw the correct exception") {
assertThrows<IllegalStateException>(assertionMessage) { }
// This should never execute:
expectAssertionFailedError()
}
assertMessageStartsWith(error, assertionMessage)
}
companion object {
fun assertExpectedExceptionTypes(
multipleFailuresError: MultipleFailuresError,
vararg exceptionTypes: KClass<out Throwable>
) =
AssertAllAssertionsTests.assertExpectedExceptionTypes(
multipleFailuresError, *exceptionTypes.map { it.java }.toTypedArray()
)
}
}