Exception Testing

Reading Time: 2 minutes

Introduction

The post will be briefly focusing on testing exceptions in Java. We will be looking at a traditional way of handling Exceptions in Junit as well as benefit from the AssertJ test library.

The case study

In this section we will see a small service that is responsible of throwing a custom checked exception only 🙂 then we will figure out how we can test the exception.

public class ProcessService {
    public void runSomeProcess(String processName) {
        String message = String.format("The process '%s' was interrupted because of unknown error", processName);
        throw new ProcessInterruptedException(message);
    }

    public static class ProcessInterruptedException extends RuntimeException {
        public ProcessInterruptedException(String message) {
            super(message);
        }
    }
}

Traditional way of testing

Generally speaking, whenever I had to test a method that resulted in an exceptional situation, I would always favored of a traditional method, assuming the expected exception would be thrown by the method and carried on.

@Test(expected = ProcessService.ProcessInterruptedException.class)
    public void shouldRunProcessAndCatchTheExceptionUsingJunit() {
        //given
        String processName = "NvidiaBackgroundScanner";

        //when - then
        processService.runSomeProcess(processName);
    }

The good old days, that just allowed me to define the expected exception in the annotation, accordingly the method invocation raises the exception.

What if we need to assert multiple things in the exception?

That’s a splendid question, isn’t it? What if we want to have a couple of checks, first and most important; the exception message. Then later the type of the exception. In this matter, the AssertJ test library comes to rescue! In the below code snippet, we will be fully covering our essential needs;

    @Test
    public void shouldRunProcessAndCatchTheExceptionUsingAssetJ() {
        //given
        String processName = "NvidiaBackgroundScanner";

        //when
        Throwable throwable = catchThrowable(() -> processService.runSomeProcess(processName));

        //then
        String expectedException = String.format("The process '%s' was interrupted because of unknown error", processName);
        assertThat(throwable).isNotNull();
        assertThat(throwable)
                .isInstanceOf(ProcessService.ProcessInterruptedException.class)
                .hasMessage(expectedException);
    }

As you can see, the AssetJ library catches the Exception and gives us ways to check the type of the Exception as well as the content! It is very simple and intuitive to test with AssertJ. That’s all folks. Last of all, here are the imports you need in the test

 import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;