Reputation: 263098
In Java, the programmer can specify expected exceptions for JUnit test cases like this:
@Test(expected = ArithmeticException.class)
public void omg()
{
int blackHole = 1 / 0;
}
How would I do this in Kotlin? I have tried two syntax variations, but none of them worked:
import org.junit.Test
// ...
@Test(expected = ArithmeticException) fun omg()
Please specify constructor invocation;
classifier 'ArithmeticException' does not have a companion object
@Test(expected = ArithmeticException.class) fun omg()
name expected ^
^ expected ')'
Upvotes: 166
Views: 116673
Reputation: 427
Assert extension that verifies the exception class and also if the error message match.
inline fun <reified T : Exception> assertThrows(runnable: () -> Any?, message: String?) {
try {
runnable.invoke()
} catch (e: Throwable) {
if (e is T) {
message?.let {
Assert.assertEquals(it, "${e.message}")
}
return
}
Assert.fail("expected ${T::class.qualifiedName} but caught " +
"${e::class.qualifiedName} instead")
}
Assert.fail("expected ${T::class.qualifiedName}")
}
for example:
assertThrows<IllegalStateException>({
throw IllegalStateException("fake error message")
}, "fake error message")
Upvotes: 3
Reputation: 546
This simple sample worked in the 4.13.2 version of Junit
@Test
fun testZeroDividing(){
var throwing = ThrowingRunnable { /*call your method here*/ Calculator().divide(1,0) }
assertThrows(/*define your exception here*/ IllegalArgumentException::class.java, throwing)
}
Upvotes: 4
Reputation: 16387
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
}
Upvotes: 23
Reputation: 263098
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)
// ...
}
Upvotes: 212
Reputation: 367
Nobody mentioned that assertFailsWith() returns the value and you can check exception attributes:
@Test
fun `my test`() {
val exception = assertFailsWith<MyException> {method()}
assertThat(exception.message, equalTo("oops!"))
}
}
Upvotes: 8
Reputation: 23711
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()
}
}
Upvotes: 130
Reputation: 22867
/**
* Example usage:
* ```kotlin
* val exception = assertThrows<IllegalArgumentException>("Should throw an Exception") {
* throw IllegalArgumentException("Talk to a duck")
* }
* assertEquals("Talk to a duck", exception.message)
* ```
* @see Assertions.assertThrows
*/
inline fun <reified T : Throwable> assertThrows(message: String, noinline executable: () -> Unit): T =
assertThrows({ message }, executable)
Upvotes: 2
Reputation: 10717
Firt steps is to add (expected = YourException::class)
in test annotation
@Test(expected = YourException::class)
Second step is to add this function
private fun throwException(): Boolean = throw YourException()
Finally you will have something like this:
@Test(expected = ArithmeticException::class)
fun `get query error from assets`() {
//Given
val error = "ArithmeticException"
//When
throwException()
val result = omg()
//Then
Assert.assertEquals(result, error)
}
private fun throwException(): Boolean = throw ArithmeticException()
Upvotes: 0
Reputation: 666
Another version of syntaxis using kluent:
@Test
fun `should throw ArithmeticException`() {
invoking {
val backHole = 1 / 0
} `should throw` ArithmeticException::class
}
Upvotes: 0
Reputation: 3165
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 }
}
}
Upvotes: 19
Reputation: 161
You can also use generics with kotlin.test package:
import kotlin.test.assertFailsWith
@Test
fun testFunction() {
assertFailsWith<MyException> {
// The code that will throw MyException
}
}
Upvotes: 16
Reputation: 43811
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() {
}
Upvotes: 29