junit

Assert ‘Exception thrown’ Junit

1. Introduction

In the Java programming language, an assertion is a statement that enables you to test your program’s presumptions. You predict that each boolean expression in an assertion will be true when the assertion is executed. If it is not true, the system will throw an error. Your assumptions about how your program will behave are confirmed by the assertion, which raises your confidence that the program is error-free by confirming that the boolean expression is in fact true.

Testing particular elements of the source code, such as classes and the methods they provide, is referred to as unit testing. Writing tests exposes whether every class and method follows or veers away from the principle that every method and class has a single, obvious responsibility. The complexity of the test increases with the method’s level of accountability. Writing tests for a huge application that is written in a single method becomes exceedingly difficult, if not impossible. Similarly to this, developing tests is simple if the program is divided into distinct classes and methods.

2. Assert exception thrown

In this section, we will see how we can write unit tests to check if the expected exception gets thrown. We will check this with both JUnit 4 and JUnit 5. First, we will create a simple class having one simple method. This method will take two parameters and will return the result of dividing the first param with the second one. As we know that the divisor cannot be 0 so we will check this before applying the division

Application.java

package org.javacodegeeks;

public class Application {

    public int divide (int a, int b) {
        if (b == 0) {
            throw new IllegalArgumentException("Divisor can't be zero");
        }
        return a/b;
    }
}

2.1 Assert Exception in JUnit 4

In this section, we will see how we can do assertions for an exception. There are multiple ways to check an exception gets thrown.

2.1.1 try-catch

The first way is to use a try/catch block. We call the testing method from a try block and will expect that the control will go to the catch block instead of the next line:

@Test
public void testExceptionThrown_tryCatch() {
    try {
        application.divide(2, 0);
        Assert.fail();
    } catch (IllegalArgumentException e) {
        // Expected
        assertEquals("Divisor can't be zero", e.getMessage());
    }
}

Here we see that the next line after application.divide(2, 0) is Assert.fail() which confirms that the control doesn’t go to that line.

2.1.2 Annotation

We can use annotation to test that the correct exception is thrown. The org.junit.Test annotation gives us a useful property expected – this is a Throwable which causes a test method to succeed if and only if an exception of the specified class is thrown by the method.

@Test(expected = IllegalArgumentException.class)
public void testExceptionThrown_annotation() {
    application.divide(2, 0);
}

One drawback of this way is that we cannot assert the error message.

2.1.3 Rule

We can use the org.junit.Rule class to assert exceptions. We define an ExpectedException instance:

@Rule public ExpectedException exceptionRule = ExpectedException.none();

When testing we use this instance to verify that the expected exception gets thrown. This is quite helpful as using this method you can check for error messages as well.

@Test
public void testExceptionThrown_rule() {
    exceptionRule.expect(IllegalArgumentException.class);
    exceptionRule.expectMessage("Divisor can't be zero");
    application.divide(2, 0);
}

ApplicationTest_JUnit4.java

package org.javacodegeeks;

import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import static org.junit.Assert.assertEquals;

public class ApplicationTest_JUnit4 {

    @Rule public ExpectedException exceptionRule = ExpectedException.none();

    private Application application = new Application();

    @Test
    public void testExceptionThrown_tryCatch() {
        try {
            application.divide(2, 0);
            Assert.fail();
        } catch (IllegalArgumentException e) {
            // Expected
            assertEquals("Divisor can't be zero", e.getMessage());
        }
    }

    @Test(expected = IllegalArgumentException.class)
    public void testExceptionThrown_annotation() {
        application.divide(2, 0);
    }

    @Test
    public void testExceptionThrown_rule() {
        exceptionRule.expect(IllegalArgumentException.class);
        exceptionRule.expectMessage("Divisor can't be zero");
        application.divide(2, 0);
    }

}
Figure 1. Running the test in IntelliJ

If you are using maven as your build tool then you can run your test by mvn test -Dtest=ApplicationTest_JUnit4

Figure 2. Run with maven

3. Assert Exception in JUnit 5

Unlike previous versions of JUnit, JUnit 5 is composed of several different modules from three different sub-projects (JUnit Platform + JUnit Jupiter + JUnit Vintage). Testing frameworks are launched on the JVM using the JUnit Platform as a base. As part of creating a testing framework that utilizes the platform, it also defines the TestEngine API. The platform also offers a Console Launcher to start it from the command line and the JUnit Platform Suite Engine to run a set of customized tests on the platform using one or more test engines. Popular IDEs like IntelliJ IDEA, Eclipse, NetBeans, and Visual Studio Code and build tools like Gradle, Maven, and Ant provide first-class support for the JUnit Platform.

For creating tests and extensions in JUnit 5, JUnit Jupiter combines the programming model and extension model. For executing Jupiter-based tests on the platform, the Jupiter sub-project offers a TestEngine. For executing JUnit 3 and JUnit 4-based tests on the platform, JUnit Vintage offers a TestEngine. It requires the presence of JUnit 4.12 or later on the classpath or module path.

ApplicationTest_JUnit5.java

package org.javacodegeeks;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

public class ApplicationTest_JUnit5 {

    private Application application = new Application();

    @Test
    public void testExceptionThrown_tryCatch() {
        Exception exception = assertThrows(IllegalArgumentException.class, () -> application.divide(2, 0));
        assertEquals("Divisor can't be zero", exception.getMessage());
    }
}
Figure 3. Running JUnit 5 test in IntelliJ

4. Conclusion

In this article, we looked at different ways of asserting that an expected exception is been thrown from a method/function in Java. First, we looked at three different ways of asserting the correct exception using JUnit4, then we looked at how we can achieve the same thing in JUnit 5.

5. Download

This was an example of comparing the assertion of exceptions thrown in a Java code using JUnit 4 and JUnit 5.

Download
You can download the full source code of this example here: Assert ‘Exception thrown’ – Java

Mohammad Meraj Zia

Senior Java Developer
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button