replayleif replayleif - 8 months ago 17
Java Question

Should I always use Lambda Expressions for Exception Tests?

I always tested my exceptions with annotations.

@Test (expected = Exception.class)
public void test1() {
methodToTest() // throws an exception

I finally switched to Java 8, and I came across lambda Expressions. Now there is another option to get the desired result.

public void test2() {
assertThrows(Exception.class, () -> methodToTest());

public static <X extends Throwable> Throwable assertThrows(
final Class<X> exceptionClass, final Runnable block) {
try {;
} catch(Throwable ex) {
if (exceptionClass.isInstance(ex))
return ex;
fail("Failed to throw expected exception");
return null;

I understand that with the second version you can check for single methods more precisely, and you don't have to worry about other methods within a single test that could throw the expected exception as well. Furthermore, with an "assertThrows" method, all tests can have the same structure, because it all comes down to a call for an assertion.

Besides those two points, are there any pro arguments for the new way? For me, it feels like its still superior to go with the annotations, as long as I am only testing a single method within a single test.


You missed a third way, the ExpectedException jUnit rule:

public class SimpleExpectedExceptionTest {
   public ExpectedException thrown= ExpectedException.none();

   public void myMethod_throws_no_exception_when_passed_greeting() {

   public void myMethod_throws_MyException_when_passed_farewell() {

I find this clearer than the @Test (expected = ...) version, since the expectation goes closer to the method call.

There is also the plain old Java version, which we used to make do with:

try {
   fixture.myMethod("should throw");
   fail("Expected an exception");
} catch (MyException e) {
   // expected  

Which of the many is "better" depends entirely on context. Don't adopt one universally. Pick the one that gives you the clearest test in a given situation.

When you begin coding non-test code in a lambda-centric style, it is likely that you'll find yourself wanting to use the lambda-centric assertThrows().