Try catch in a JUnit test

You can add exception in test method signature. Then, if you are testing whether exception is thrown, you have to use @Test(expected=Exception.class). In the test cases where exception has not to be thrown, test will pass successfully.

@Test
public void testCaseWhereExceptionWontBeThrown() throws Exception {
    someMethod(); //Test pass
}

@Test(expected = Exception.class)
public void testCaseWhereExceptionWillBeThrown() throws Exception {
    someMethod(); //Test pass
}

Do not catch your application's exception in your test code. Instead, declare it to be thrown upwards.

Because, when JUnit's TestRunner finds an exception thrown, it will automatically log it as an error for the testcase.

Only if you testcase expects that the method should thrown an Exception you should use @Test(expected=Exception.class) or catch the exception.

In other cases, just throw it upwards with,

public void someTest() throws Exception {

@Test
public void someTest() {
   try {
     someMethod();
   }
   catch (Exception e) {
     Assert.fail("Exception " + e);
   }
}

Is what you can do, if the exception should not occur. An alternative would be to throw the exception in the signature like this:

@Test
public void someTest() throws Exception {
     someMethod();
}

The difference is, that in one case the test will fail with an assertion exception and in the other case it will fail because the test crashed. (like somewhere in your code you get a NPE and the test will because of that)

The reason you have to do this, is because Exception is a checked exception. See Checked versus unchecked exception

The @Test(expected=Exception.class) is for tests, that want to test that the exception will be thrown.

@Test(expected=ArrayIndexOutOfBounds.class)
public void testIndex() {
   int[] array = new int[0];
   int var = array[0]; //exception will be thrown here, but test will be green, because we expect this exception

}

Since Exception is a checked exception, you either:

  • Have to catch the exception in a try...catch statement, or
  • Declare the exception to be thrown in the method itself.

What you have up there works fine, but my personal preference is to declare the exception to be thrown. This way, if an exception I'm not expecting is thrown during the run of the test, the test will fail.

@Test
public void someTest() throws Exception {
    // dodgy code here
}

If we need to see if a specific exception is thrown, then you have the option of using @Rule or adding the value to the @Test annotation directly.

@Test(expected = FileNotFoundException.class)
public void someTest() throws Exception {
    // dodgy code here
}

In JUnit 5, you can leverage Assertions.assertThrows to accomplish the same thing. I'm less familiar with this overall since it's not yet GA at the time of editing, but it appears to accept an Executable coming from JUnit 5.

@Test
public void someTest() {
    assertThrows(FileNotFoundException.class, () ->
         { dodgyService.breakableMethod() };
}