Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Test expected exceptions in Kotlin

People also ask

How do you test an exception that is not thrown?

If you want to test a scenario in which an exception should be thrown then you should use the expected annotation. If you want to test a scenario where your code fails and you want to see if the error is correctly handled: use expected and perhaps use asserts to determine if it's been resolved.

Why does Kotlin not have checked exceptions?

Kotlin Exceptions All exception classes descend from the class Throwable. Kotlin uses the throw keyword to throw an exception object. Although Kotlin inherits the concept of exception from Java, it doesn't support checked exceptions like Java. The checked exceptions are considered a controversial feature in Java.

What are expected exceptions?

The ExpectedException rule allows you to verify that your code throws a specific exception.


The Kotlin translation of the Java example for JUnit 4.12 is:

@Test(expected = ArithmeticException::class)
fun omg() {
    val blackHole = 1 / 0
}

However, JUnit 4.13 introduced two assertThrows methods for finer-granular exception scopes:

@Test
fun omg() {
    // ...
    assertThrows(ArithmeticException::class.java) {
        val blackHole = 1 / 0
    }
    // ...
}

Both assertThrows methods return the expected exception for additional assertions:

@Test
fun omg() {
    // ...
    val exception = assertThrows(ArithmeticException::class.java) {
        val blackHole = 1 / 0
    }
    assertEquals("/ by zero", exception.message)
    // ...
}

Kotlin has its own test helper package that can help to do this kind of unittest.

Your test can be very expressive by use assertFailWith:

@Test
fun test_arithmethic() {
    assertFailsWith<ArithmeticException> {
        omg()
    }
}

You can use @Test(expected = ArithmeticException::class) or even better one of Kotlin's library methods like failsWith().

You can make it even shorter by using reified generics and a helper method like this:

inline fun <reified T : Throwable> failsWithX(noinline block: () -> Any) {
    kotlin.test.failsWith(javaClass<T>(), block)
}

And example using the annotation:

@Test(expected = ArithmeticException::class)
fun omg() {

}

You can use Kotest for this.

In your test, you can wrap arbitrary code with a shouldThrow block:

shouldThrow<ArithmeticException> {
  // code in here that you expect to throw a ArithmeticException
}

JUnit5 has kotlin support built in.

import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows

class MyTests {
    @Test
    fun `division by zero -- should throw ArithmeticException`() {
        assertThrows<ArithmeticException> {  1 / 0 }
    }
}

You can also use generics with kotlin.test package:

import kotlin.test.assertFailsWith 

@Test
fun testFunction() {
    assertFailsWith<MyException> {
         // The code that will throw MyException
    }
}