- assertFailsWith
- Test expected exceptions in Kotlin
- Unit Testing Solutions
- Solution 1 — Unit Testing
- Solution 2 — Unit Testing
- Solution 3 — Unit Testing
- Solution 4 — Unit Testing
- Solution 5 — Unit Testing
- Solution 6 — Unit Testing
- Solution 7 — Unit Testing
- Solution 8 — Unit Testing
- Solution 9 — Unit Testing
- org.junit.jupiter.api.Assertions.kt
- Solution 10 — Unit Testing
- Solution 11 — Unit Testing
- Solution 12 — Unit Testing
- Inspecting drop down menus in new Chrome
- How can I check if a module has been imported?
- Attributions
- Testing exceptions in Kotlin with `assertFailsWith`
assertFailsWith
Asserts that a block fails with a specific exception of type T being thrown.
If the assertion fails, the specified message is used unless it is null as a prefix for the failure message.
Return An exception of the expected exception type T that successfully caught. The returned exception can be inspected further, for example by asserting its property values.
@JvmName ( «assertFailsWithInline» ) inline fun < T : Throwable > assertFailsWith (
exceptionClass : KClass < T >,
block : ( ) -> Unit
) : T
(source)
Asserts that a block fails with a specific exception of type exceptionClass being thrown.
Return An exception of the expected exception type T that successfully caught. The returned exception can be inspected further, for example by asserting its property values.
@JvmName ( «assertFailsWithInline» ) inline fun < T : Throwable > assertFailsWith (
exceptionClass : KClass < T >,
message : String ? ,
block : ( ) -> Unit
) : T
(source)
Asserts that a block fails with a specific exception of type exceptionClass being thrown.
If the assertion fails, the specified message is used unless it is null as a prefix for the failure message.
Return An exception of the expected exception type T that successfully caught. The returned exception can be inspected further, for example by asserting its property values.
Test expected exceptions in Kotlin
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 ')'
Unit Testing Solutions
Solution 1 — Unit Testing
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) // . >
Solution 2 — Unit Testing
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 < omg() >>
Solution 3 — Unit Testing
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(), block) >
And example using the annotation:
@Test(expected = ArithmeticException::class) fun omg()
Solution 4 — Unit Testing
In your test, you can wrap arbitrary code with a shouldThrow block:
shouldThrow < // code in here that you expect to throw a ArithmeticException >
Solution 5 — Unit Testing
You can also use generics with kotlin.test package:
import kotlin.test.assertFailsWith @Test fun testFunction() < assertFailsWith< // The code that will throw MyException > >
Solution 6 — Unit Testing
import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows class MyTests < @Test fun `division by zero -- should throw ArithmeticException`() < assertThrows< 1 / 0 > > >
Solution 7 — Unit Testing
Nobody mentioned that assertFailsWith() returns the value and you can check exception attributes:
@Test fun `my test`() < val exception = assertFailsWith assertThat(exception.message, equalTo("oops!")) > >
Solution 8 — Unit Testing
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, "$ ") > return > Assert.fail("expected $ but caught " + "$ instead") > Assert.fail("expected $ ")
assertThrows(< throw IllegalStateException("fake error message") >, "fake error message")
Solution 9 — Unit Testing
org.junit.jupiter.api.Assertions.kt
/** * Example usage: * ```kotlin * val exception = assertThrows("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)
Solution 10 — Unit Testing
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) >
Solution 11 — Unit Testing
Another version of syntaxis using kluent:
@Test fun `should throw ArithmeticException`() < invoking < val backHole = 1 / 0 > `should throw` ArithmeticException::class >
Solution 12 — Unit Testing
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()
Inspecting drop down menus in new Chrome
How can I check if a module has been imported?
Attributions
All content for this solution is sourced from the original question on Stackoverflow.
The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.
Content Type | Original Author | Original Content on Stackoverflow |
---|---|---|
Question | fredoverflow | View Question on Stackoverflow |
Solution 1 — Unit Testing | fredoverflow | View Answer on Stackoverflow |
Solution 2 — Unit Testing | Michele d’Amico | View Answer on Stackoverflow |
Solution 3 — Unit Testing | Kirill Rakhman | View Answer on Stackoverflow |
Solution 4 — Unit Testing | sksamuel | View Answer on Stackoverflow |
Solution 5 — Unit Testing | Majid | View Answer on Stackoverflow |
Solution 6 — Unit Testing | Frank Neblung | View Answer on Stackoverflow |
Solution 7 — Unit Testing | Svetopolk | View Answer on Stackoverflow |
Solution 8 — Unit Testing | Yanay Hollander | View Answer on Stackoverflow |
Solution 9 — Unit Testing | Braian Coronel | View Answer on Stackoverflow |
Solution 10 — Unit Testing | Ali Doran | View Answer on Stackoverflow |
Solution 11 — Unit Testing | alexlz | View Answer on Stackoverflow |
Solution 12 — Unit Testing | Cabezas | View Answer on Stackoverflow |
Testing exceptions in Kotlin with `assertFailsWith`
I wanted to write this short post to highlight the assertFailsWith function available to Kotlin that makes testing exceptions a bit easier. Testing exceptions isn’t something fancy or new to JVM languages (from now on I will use Java for comparisons) but Kotlin comes with the nice extra benefit of providing this functionality as part of its standard library. Comparing this to Java, you are likely to bring AssertJ into the mix to achieve similar results.
The main purpose of this post is to make you aware of the assertFailsWith function. I personally did not know it existed for a while and defaulted to depending on AssertJ. Not that I have anything against AssertJ that is. There are many other features that the library provides but for this specific instance it might be possible to remove it (assuming you are not using it for anything else that is).
What is good about assertFailsWith and AssertJ in general? It provides better exception testing than the simple constructs that JUnit provides. More precisely, it allows you to specify which part of your test that you expect an exception to be thrown, instead of declaring that an exception will arise somewhere in the code. This could lead to exceptions being incorrectly swallowed by test at an incorrect point and tricking you into thinking it is working as you think it should.
Now I have that brief point out of the way, let’s get on with the main content of this post. Below is what assertFailsWith looks like inside a test:
@Test fun `calling hereIsAnException will return an exception no matter what`() assertFailsWithIllegalArgumentException> hereIsAnException() > >
In this example, hereIsAnException is placed inside the body of assertFailsWith , who checks that an IllegalArgumentException is thrown. If one is not raised, then the assertion will fail. If one does occur, then the assertion will pass and the exception is caught.
Catching the exception allows the execution of the test code to continue if needed as well as allowing you to make further assertions on the state of the exception.
For example, is it a wrapper around another exception (what is the type of its cause property)?
@Test fun `original cause for exception was IndexOutOfBoundsException`() val exception = assertFailsWithIllegalArgumentException> hereIsAnException() > assertTrue(exception.cause is IndexOutOfBoundsException) >
Is the message what you expect (not the most sturdy of checks)?
@Test fun `exception has the correct message`() val exception = assertFailsWithIllegalArgumentException> hereIsAnException() > assertEquals("I am a failure. ", exception.message) >
Only exceptions that are of the same type or sub type as specified by assertFailsWith will be caught. Any others will cause the test to to fail. Since it catches sub types, please don’t go around just specifying Exception or RuntimeException . Try to be precise so your tests are as useful as possible.
As touched on earlier, assertFailsWith will only catch an exception that is thrown within the body of the function. Therefore if this was written instead:
@Test fun `calling hereIsAnException will return an exception no matter what`() hereIsAnException() assertFailsWithIllegalArgumentException> hereIsAnException() > >
The test would fail. hereIsAnException has thrown an exception, which has not been caught and leads to the test failing. I believe this is the best part of this sort of function over the previous ways this used to be done (e.g. asserting inside @Test that an exception would occur).
@Test fun `calling hereIsAnException will return an exception no matter what`() assertFailsWithIllegalArgumentException>("This should throw an illegal argument exception") hereIsANormalReturnValue() > >
I personally have never really used the message part of an assertion. Maybe you do, so, I thought I’d at least let you know.
Before I wrap up the little amount of content in this post, let’s have a quick look at AssertJ so that we can draw a comparison between the two. Again, this is only for the case of catching exceptions which is only a small part of what AssertJ provides.
@Test fun `calling hereIsAnException will return an exception no matter what`() assertThatExceptionOfType(IllegalArgumentException::class.java).isThrownBy hereIsAnException() > >
This is slightly more “verbose” than the assertFailsWith version. But, that is made up for with the plethora of functions that AssertJ provides that makes any further checking of the returned exception much easier. More precisely, when using assertFailsWith I needed to write another assertion to check the message. In AssertJ this is just a function chained onto the end of the previous call.
To conclude, assertFailsWith is a nice little function to use in testing to ensure that a piece of code throws a specific type of exception. It is built in to the Kotlin standard library which removes the need to bring in an extra dependency to your project. That being said, it is a relatively simple function and does not bring the sort of functionality that a library like AssertJ would. It is likely to suffice until you want to write tests that contain a wide range or assertions as this is the point where it can get messy.
The official docs for assertFailsWith can be found here if you are interested Kotlin Docs — assertFailsWith.
If you found this post helpful, you can follow me on Twitter at @LankyDanDev to keep up with my new posts.