1. Overview

In this tutorial, we’re going to discuss testing exceptions in Kotlin with the assertFailsWith method.

We’ll first cover how we can use the JUnit 5 library to test exceptions and then move on to discuss the assertFailsWith method.

2. Using JUnit 5

Exceptions disrupt normal program execution flow and are an essential part of any JVM language. Handling execution is the technique to gracefully handle such problems.

In Kotin, we can use different libraries to test that exceptions are thrown, the most popular of them being the JUnit library.

JUnit 5 Jupiter API provides several assertion methods to determine the pass or fail status of a test case. More specifically, JUnit 5 provides a couple of assertion methods that are more suitable for the Kotlin language.

One such method in JUnit 5 that we can use to assert exceptions in Kotlin is assertThrows(). In addition, this function allows us to add a block of code after the assertion call to make this more readable:

fun whenInvalidArray_thenThrowsException() {
    assertThrows<ArrayIndexOutOfBoundsException> {
        val array = intArrayOf(1, 2, 3)
        array[5]
    }
}

In this example, the assertion is successful when the expected ArrayIndexOutOfBoundsException is thrown from the block of code. Additionally, the assertion also works when the block of code throws an exception that is a derived type of ArrayIndexOutOfBoundsException.

3. Using Kotlin’s assertFailsWith Method

The Kotlin standard library also provides a function to test exceptions. We can use the assertFailsWith method to assert that a block of code fails with an exception type.

In addition, we can also define a message as a parameter to the function. The message is optional and is used as a prefix to the failure message only when the assertion fails:

fun givenInvalidArray_thenThrowsException() {
    assertFailsWith<ArrayIndexOutOfBoundsException>(
        message = "No exception found",
        block = {
            val array = intArrayOf(1, 2, 3)
            array[5]
        }
    )
}

In the example above, the assertion passes when the block throws an ArrayIndexOutOfBoundsException. If the assertion fails, then the message is displayed.

Alternatively, we can use the assertFailsWith method to assert that a block of code fails with a specific exception class. This exception class is defined as a parameter to the function along with the block of code:

fun givenInvalidFormat_thenThrowsException() {
    assertFailsWith(
        exceptionClass = NumberFormatException::class,
        block = { "Kotlin Tutorials in Baeldung".toInt() }
    )
}

In this example, the assertion expects a NumberFormatException to be thrown from the block of code.

Furthermore, we can also use the assertFailsWith method to include both the specific exception class and the message as parameters along with the block of code:

fun givenInvalidOperation_thenThrowsException() {
    assertFailsWith(
        exceptionClass = ArithmeticException::class,
        message = "No exception found",
        block = { 50 * 12 / 0 }
    )
}

In this case above, the assertFailsWith method asserts that the code block throws the defined ArithmeticException. The specified message is used in the scenario where the assertion fails.

3.1. Asserting Exception Attributes

The assertFailsWith method always returns an exception type. The returned value can be inspected further to assert exception attributes:

fun givenInvalidNumericFormat_thenThrowsException() {
    val exception = assertFailsWith<NumberFormatException>(
        block = { Integer.parseInt("abcdefgh") }
    )
    assertThat(exception.message, equalTo("For input string: \"abcdefgh\""))
}

In this example, the assertFailsWith method returns the exception if the assertion is successful. This further enables us to assert the message attribute of the exception.

The assertFailsWith method always catches exceptions that are of the same type or their subtype. But we should always try to be precise so that the tests are useful instead of just specifying Exception or RuntimeException.

Since the assertFailsWith method is included in the Kotlin standard library, it reduces the overhead of including any extra library in our test code.

So, it’s useful when we want to write simple unit tests to assert exceptions. But, the JUnit assertion methods will be more suitable if we want to write unit tests that involve multiple assertions.

4. Conclusion

In this tutorial, we discussed testing exceptions in Kotlin using the assertFailsWith method.

As always, the code for these examples is available over on GitHub.

To learn more about Kotlin features, have a glance at one of our Kotlin tutorials.

guest
0 Comments
Inline Feedbacks
View all comments