Introduce 'fail' method to throw AssertionError with cause

#KT-37804
This commit is contained in:
Ilya Gorbunov
2020-01-26 00:02:43 +03:00
parent d2ff98fcb1
commit 2bb36899da
11 changed files with 95 additions and 13 deletions
@@ -92,6 +92,17 @@ fun fail(message: String? = null): Nothing {
asserter.fail(message)
}
/**
* Marks a test as having failed if this point in the execution path is reached, with an optional [message]
* and [cause] exception.
*
* The [cause] exception is set as the root cause of the test failure.
*/
@SinceKotlin("1.4")
fun fail(message: String? = null, cause: Throwable? = null): Nothing {
asserter.fail(message, cause)
}
/** Asserts that given function [block] returns the given [expected] value. */
fun <@OnlyInputTypes T> expect(expected: T, block: () -> T) {
assertEquals(expected, block())
@@ -173,6 +184,8 @@ inline fun <T : Throwable> assertFailsWith(exceptionClass: KClass<T>, block: ()
inline fun <T : Throwable> assertFailsWith(exceptionClass: KClass<T>, message: String?, block: () -> Unit): T =
checkResultIsFailure(exceptionClass, message, runCatching(block))
/** Platform-specific construction of AssertionError with cause */
internal expect fun AssertionErrorWithCause(message: String?, cause: Throwable?): AssertionError
/**
* Abstracts the logic for performing assertions. Specific implementations of [Asserter] can use JUnit
@@ -186,6 +199,15 @@ interface Asserter {
*/
fun fail(message: String?): Nothing
/**
* Fails the current test with the specified message and cause exception.
*
* @param message the message to report.
* @param cause the exception to set as the root cause of the reported failure.
*/
@SinceKotlin("1.4")
fun fail(message: String?, cause: Throwable?): Nothing
/**
* Asserts that the specified value is `true`.
*
@@ -15,6 +15,11 @@ object DefaultAsserter : Asserter {
else
throw AssertionError(message)
}
@SinceKotlin("1.4")
override fun fail(message: String?, cause: Throwable?): Nothing {
throw AssertionErrorWithCause(message, cause)
}
}
@Deprecated("DefaultAsserter is an object now, constructor call is not required anymore",
@@ -148,7 +148,7 @@ class BasicAssertionsTest {
@Test()
fun testAssertNotNullFails() {
checkFailedAssertion { assertNotNull(null) }
checkFailedAssertion { assertNotNull<Any>(null) }
}
@Test
@@ -178,7 +178,18 @@ class BasicAssertionsTest {
@Test()
fun testFail() {
checkFailedAssertion { fail("should fail") }
val message = "should fail"
val actual = checkFailedAssertion { fail(message) }
assertEquals(message, actual.message)
}
@Test
fun testFailWithCause() {
val message = "should fail due to"
val cause = IllegalStateException()
val actual = checkFailedAssertion { fail(message, cause) }
assertEquals(message, actual.message)
assertSame(cause, actual.cause)
}
@Test
@@ -193,8 +204,8 @@ class BasicAssertionsTest {
}
private fun checkFailedAssertion(assertion: () -> Unit) {
assertFailsWith<AssertionError> { withDefaultAsserter(assertion) }
private fun checkFailedAssertion(assertion: () -> Unit): AssertionError {
return assertFailsWith<AssertionError> { withDefaultAsserter(assertion) }
}
private fun withDefaultAsserter(block: () -> Unit) {