Issue
When using Java and assertThrows:
public static <T extends Throwable> T assertThrows(Class<T> expectedType, Executable executable)
we can write simple lambda function:
@Test
void testExpectedException() {
Assertions.assertThrows(NumberFormatException.class, () -> {
Integer.parseInt("One");
});
}
How we can do this in Groovy?
I was trying something like:
@Test
void testExpectedException() {
assertThrows(NumberFormatException.class, {
Integer.parseInt("One");
}())
}
but the error is thrown and not caught:
java.lang.format.NumberFormatException: For ....
Solution
There is one mistake in your test method. Instead of coercing a closure to an Executable
type, you passed a result of calling a closure. The correct syntax is:
@Test
void testExpectedException() {
assertThrows(NumberFormatException.class, {
Integer.parseInt("One");
})
}
You can make it even "groovier" with:
@Test
void testExpectedException() {
assertThrows(NumberFormatException) {
Integer.parseInt("One")
}
}
This second example uses popular Groovy idiom - when the method's last parameter is a closure, you can put it outside the parenthesis. It looks like a code block, but it is just a closure passed as a second parameter to the method.
In the Java example, you have used a lambda expression passed as an instance of Executable
functional interface. Groovy's equivalent for that (at least in Groovy 2.x version - support for lambda expressions is added in Groovy 3) is closure coercion to SAM type (single abstract method). The above example shows how to define an instance of the Executable
type with a closure. If you put ()
after the closure closing brace, you make a shortcut to a call()
method execution. This method executes closure's body.
Answered By - Szymon Stepniak
Answer Checked By - Marilyn (JavaFixing Volunteer)