How to Assert Exceptions in JUnit 4 and JUnit 5?

Last Updated : 23 Jul, 2025

In software testing, particularly in the unit tests, verifying that the code throws the expected exceptions under certain conditions is crucial. JUnit is the widely used testing framework for the Java, it allows us to assert exceptions using the different approaches depending on the version (JUnit 4 or JUnit 5).

In this article, we will learn the methods to the assert exceptions in both JUnit 4 and JUnit 5, with step-by-step examples.

Prerequisites:

  • Basic understanding of the Java and unit testing.
  • JUnit 4 or JUnit 5 dependency in the project.
  • Maven for building dependency management.
  • JDK and IntelliJ IDEA installed in your system.

Exception Handling in JUnit 4

JUnit 4 provides two main approaches for handling the exceptions in the unit tests:

  1. Using the @Test(expected = Exception.class)
  2. Using the try-catch with assertions

Using @Test(expected = Exception.class)

In JUnit 4, the expected attribute of the @Test annotation allows you to specify an exception that you expect to be thrown. This approach is concise and efficient.

Example:

import org.junit.Test;

public class JUnit4ExceptionTest {
@Test(expected = IllegalArgumentException.class)
public void testExceptionThrown() {
// Code that should throw IllegalArgumentException
throw new IllegalArgumentException("Invalid argument");
}
}

In this example:

  • The @Test annotation uses the expected attribute to specify the expected exception type.
  • The testExceptionThrown method passes if IllegalArgumentException is thrown; otherwise, it fails.

Using Try-Catch with Assertions

Alternatively, you can use a try-catch block to catch exceptions manually and assert the exception type and message, allowing for more detailed assertions.

Example:

import org.junit.Assert;
import org.junit.Test;

public class JUnit4TryCatchTest {
@Test
public void testExceptionThrown() {
try {
throw new IllegalArgumentException("Invalid argument");
} catch (IllegalArgumentException e) {
Assert.assertEquals("Invalid argument", e.getMessage());
}
}
}

In this example,

  • The try-catch block catches IllegalArgumentException.
  • The Assert.assertEquals method verifies that the exception message matches the expected value.

Exception Handling in JUnit 5

JUnit 5 offers a approach for asserting exceptions using Assertions.assertThrows(), which captures the thrown exception and allows further assertions.

Using Assertions.assertThrows()

The assertThrows method is preferred for testing exceptions in JUnit 5. It requires specifying the exception type and a lambda expression that includes the code expected to throw the exception.

Example:

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class JUnit5ExceptionTest {
@Test
public void testExceptionThrown() {
IllegalArgumentException exception = Assertions.assertThrows(IllegalArgumentException.class, () -> {
throw new IllegalArgumentException("Invalid argument");
});
Assertions.assertEquals("Invalid argument", exception.getMessage());
}
}

In this example,

  • Assertions.assertThrows is used to assert that IllegalArgumentException is thrown.
  • The returned exception allows further assertions, such as verifying the exception message.

Testing Absence of Exceptions Using assertDoesNotThrow()

JUnit 5 introduces assertDoesNotThrow(), which ensures that no exception is thrown from a given code segment.

Example:

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class JUnit5NoExceptionTest {
@Test
public void testNoExceptionThrown() {
Assertions.assertDoesNotThrow(() -> {

});
}
}

This method is helpful when you need to verify that certain code does not throw exceptions, providing a cleaner alternative than JUnit 4.

Project Implementation to Assert Exceptions in JUnit 4 and JUnit 5

In this example project, we demonstrate how to assert exceptions in both JUnit 4 and JUnit 5 using a simple service class that throws an exception under specific conditions.

Step 1: Create a Maven Project

  • Project Name: exception-handling-example
  • Build System: Maven

Click on the Create button.

Project Metadata

Project Structure

After project creation done, set the project folder structure as shown in the below image:

Project Folder Structure

Step 2: Add the JUnit 4 and JUnit 5 Dependencies to pom.xml

Open the pom.xml file and add the JUnit 4 and JUnit 5 dependencies into the Maven project.

XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0"
         xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.gfg</groupId>
    <artifactId>exception-handling-example</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <!-- JUnit 4 Dependency -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>

        <!-- JUnit 5 Dependency -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.8.2</version>
            <scope>test</scope>
        </dependency>
        <!-- JUnit Vintage Engine for running JUnit 4 tests in JUnit 5 -->
        <dependency>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
            <version>5.8.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
        <!-- Maven Surefire Plugin for JUnit 5 -->
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.22.2</version>
                    <configuration>
                        <includes>
                            <include>**/*Test.java</include>
                        </includes>
                    </configuration>
                </plugin>
            </plugins>
        </build>
</project>

Step 3: Service Class

MyService.java:

Java
package com.gfg;

public class MyService {

    public void validateInput(int number) {
        if (number < 0) {
            throw new InvalidInputException("Negative numbers are not allowed.");
        }
    }
}

Step 4: Custom Exception Class

InvalidInputException.java:

Java
package com.gfg;

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

Step 5: Main Class

Java
package com.gfg;

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        MyService myService = new MyService();
        Scanner scanner = new Scanner(System.in);

        System.out.println("Enter a number:");
        int input = scanner.nextInt();

        try {
            myService.validateInput(input);
        } catch (InvalidInputException e) {
            System.err.println("Error: " + e.getMessage());
        } finally {
            scanner.close();
        }

    }
}

Step 6: JUnit 4 Test Class

MyServiceJUnit4Test.java:

Java
import com.gfg.InvalidInputException;
import com.gfg.MyService;
import org.junit.Assert;
import org.junit.Test;

public class MyServiceJUnit4Test {
    private final MyService myService = new MyService();

    @Test(expected = InvalidInputException.class)
    public void testValidateInputThrowsException() {
        myService.validateInput(-1);
    }

    @Test
    public void testValidateInputExceptionMessage() {
        try {
            myService.validateInput(-1);
        } catch (InvalidInputException e) {
            Assert.assertEquals("Negative numbers are not allowed.", e.getMessage());
        }
    }
}

Step 7: JUnit 5 Test Class

MyServiceJUnit5Test.java:

Java
import com.gfg.InvalidInputException;
import com.gfg.MyService;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class MyServiceJUnit5Test {
    private final MyService myService = new MyService();

    @Test
    public void testValidateInputThrowsException() {
        InvalidInputException exception = Assertions.assertThrows(InvalidInputException.class, () -> {
            myService.validateInput(-1);
        });
        Assertions.assertEquals("Negative numbers are not allowed.", exception.getMessage());
    }
}

Step 8: Run the Application

Once the project is completed, we will run the application and it will display the below output:

Console Output


Exception case:

Exception Occurs

Step 9: Running the test

We will now run the tests using the below command.

mvn test

Output:

Test Output

We should see the output indicating that all the tests passed successfully.

This example project demonstrates how to assert exceptions in both JUnit 4 and JUnit 5. By using both JUnit versions, we can see the differences in the syntax and flexibility when handling exceptions. It can be extended with more complex scenarios, but it serves as the foundational reference for exception handling in the unit tests.

Comment

Explore