@@ -285,6 +285,39 @@ inline fun <reified T : Throwable> assertThrows(executable: () -> Unit): T {
285285 }
286286}
287287
288+ /* *
289+ * Example usage:
290+ * ```kotlin
291+ * val exception = assertThrows(IllegalArgumentException::class.java) {
292+ * throw IllegalArgumentException("Talk to a duck")
293+ * }
294+ * assertEquals("Talk to a duck", exception.message)
295+ * ```
296+ *
297+ * This version of assertThrows is intended to be used in situations where reified Throwable's cannot be used,
298+ * i.e. when using a @ParameterizedTest that provides exception classes as values.
299+ * @see Assertions.assertThrows
300+ */
301+ inline fun <T : Throwable > assertThrows (
302+ expectedType : Class <T >,
303+ executable : () -> Unit
304+ ): T {
305+ // no contract for `executable` because it is expected to throw an exception instead
306+ // of being executed completely (see https://youtrack.jetbrains.com/issue/KT-27748)
307+ val throwable: Throwable ? =
308+ try {
309+ executable()
310+ } catch (caught: Throwable ) {
311+ caught
312+ } as ? Throwable
313+
314+ return Assertions .assertThrows(expectedType) {
315+ if (throwable != null ) {
316+ throw throwable
317+ }
318+ }
319+ }
320+
288321/* *
289322 * Example usage:
290323 * ```kotlin
@@ -300,6 +333,25 @@ inline fun <reified T : Throwable> assertThrows(
300333 executable : () -> Unit
301334): T = assertThrows({ message }, executable)
302335
336+ /* *
337+ * Example usage:
338+ * ```kotlin
339+ * val exception = assertThrows(IllegalArgumentException::class.java, "Should throw an Exception") {
340+ * throw IllegalArgumentException("Talk to a duck")
341+ * }
342+ * assertEquals("Talk to a duck", exception.message)
343+ * ```
344+ *
345+ * This version of assertThrows is intended to be used in situations where reified Throwable's cannot be used,
346+ * i.e. when using a @ParameterizedTest that provides exception classes as values.
347+ * @see Assertions.assertThrows
348+ */
349+ inline fun <T : Throwable > assertThrows (
350+ expectedType : Class <T >,
351+ message : String ,
352+ executable : () -> Unit
353+ ): T = assertThrows(expectedType, { message }, executable)
354+
303355/* *
304356 * Example usage:
305357 * ```kotlin
@@ -339,6 +391,49 @@ inline fun <reified T : Throwable> assertThrows(
339391 )
340392}
341393
394+ /* *
395+ * Example usage:
396+ * ```kotlin
397+ * val exception = assertThrows(IllegalArgumentException::class.java, { "Should throw an Exception" }) {
398+ * throw IllegalArgumentException("Talk to a duck")
399+ * }
400+ * assertEquals("Talk to a duck", exception.message)
401+ * ```
402+ *
403+ * This version of assertThrows is intended to be used in situations where reified Throwable's cannot be used,
404+ * i.e. when using a @ParameterizedTest that provides exception classes as values.
405+ * @see Assertions.assertThrows
406+ */
407+ @OptIn(ExperimentalContracts ::class )
408+ inline fun <T : Throwable > assertThrows (
409+ expectedType : Class <T >,
410+ noinline message : () -> String ,
411+ executable : () -> Unit
412+ ): T {
413+ contract {
414+ callsInPlace(message, AT_MOST_ONCE )
415+ // no contract for `executable` because it is expected to throw an exception instead
416+ // of being executed completely (see https://youtrack.jetbrains.com/issue/KT-27748)
417+ }
418+
419+ val throwable: Throwable ? =
420+ try {
421+ executable()
422+ } catch (caught: Throwable ) {
423+ caught
424+ } as ? Throwable
425+
426+ return Assertions .assertThrows(
427+ expectedType,
428+ {
429+ if (throwable != null ) {
430+ throw throwable
431+ }
432+ },
433+ message
434+ )
435+ }
436+
342437/* *
343438 * Example usage:
344439 * ```kotlin
@@ -366,6 +461,39 @@ inline fun <reified T : Throwable> assertThrowsExactly(executable: () -> Unit):
366461 }
367462}
368463
464+ /* *
465+ * Example usage:
466+ * ```kotlin
467+ * val exception = assertThrows(IllegalArgumentException::class.java) {
468+ * throw IllegalArgumentException("Talk to a duck")
469+ * }
470+ * assertEquals("Talk to a duck", exception.message)
471+ * ```
472+ *
473+ * This version of assertThrowsExactly is intended to be used in situations where reified Throwable's cannot be used,
474+ * i.e. when using a @ParameterizedTest that provides exception classes as values.
475+ * @see Assertions.assertThrowsExactly
476+ */
477+ inline fun <T : Throwable > assertThrowsExactly (
478+ expectedType : Class <T >,
479+ executable : () -> Unit
480+ ): T {
481+ // no contract for `executable` because it is expected to throw an exception instead
482+ // of being executed completely (see https://youtrack.jetbrains.com/issue/KT-27748)
483+ val throwable: Throwable ? =
484+ try {
485+ executable()
486+ } catch (caught: Throwable ) {
487+ caught
488+ } as ? Throwable
489+
490+ return Assertions .assertThrowsExactly(expectedType) {
491+ if (throwable != null ) {
492+ throw throwable
493+ }
494+ }
495+ }
496+
369497/* *
370498 * Example usage:
371499 * ```kotlin
@@ -381,6 +509,25 @@ inline fun <reified T : Throwable> assertThrowsExactly(
381509 executable : () -> Unit
382510): T = assertThrowsExactly({ message }, executable)
383511
512+ /* *
513+ * Example usage:
514+ * ```kotlin
515+ * val exception = assertThrowsExactly(IllegalArgumentException::class.java, "Should throw an Exception") {
516+ * throw IllegalArgumentException("Talk to a duck")
517+ * }
518+ * assertEquals("Talk to a duck", exception.message)
519+ * ```
520+ *
521+ * This version of assertThrowsExactly is intended to be used in situations where reified Throwable's cannot be used,
522+ * i.e. when using a @ParameterizedTest that provides exception classes as values.
523+ * @see Assertions.assertThrowsExactly
524+ */
525+ inline fun <T : Throwable > assertThrowsExactly (
526+ expectedType : Class <T >,
527+ message : String ,
528+ executable : () -> Unit
529+ ): T = assertThrowsExactly(expectedType, { message }, executable)
530+
384531/* *
385532 * Example usage:
386533 * ```kotlin
@@ -420,6 +567,49 @@ inline fun <reified T : Throwable> assertThrowsExactly(
420567 )
421568}
422569
570+ /* *
571+ * Example usage:
572+ * ```kotlin
573+ * val exception = assertThrowsExactly(IllegalArgumentException::class.java, { "Should throw an Exception" }) {
574+ * throw IllegalArgumentException("Talk to a duck")
575+ * }
576+ * assertEquals("Talk to a duck", exception.message)
577+ * ```
578+ *
579+ * This version of assertThrowsExactly is intended to be used in situations where reified Throwable's cannot be used,
580+ * i.e. when using a @ParameterizedTest that provides exception classes as values.
581+ * @see Assertions.assertThrowsExactly
582+ */
583+ @OptIn(ExperimentalContracts ::class )
584+ inline fun <T : Throwable > assertThrowsExactly (
585+ expectedType : Class <T >,
586+ noinline message : () -> String ,
587+ executable : () -> Unit
588+ ): T {
589+ contract {
590+ callsInPlace(message, AT_MOST_ONCE )
591+ // no contract for `executable` because it is expected to throw an exception instead
592+ // of being executed completely (see https://youtrack.jetbrains.com/issue/KT-27748)
593+ }
594+
595+ val throwable: Throwable ? =
596+ try {
597+ executable()
598+ } catch (caught: Throwable ) {
599+ caught
600+ } as ? Throwable
601+
602+ return Assertions .assertThrowsExactly(
603+ expectedType,
604+ {
605+ if (throwable != null ) {
606+ throw throwable
607+ }
608+ },
609+ message
610+ )
611+ }
612+
423613/* *
424614 * Example usage:
425615 * ```kotlin
0 commit comments