JUnit 5: How to assert an exception is thrown

Backend Pro

1. Introduction

It is considered a best practice to perform unit testing on every line of code that is written for production purposes. In Java, when handling exceptions, we may choose to suppress them, re-throw them, or even create custom exceptions.

Writing JUnit tests for all exception handling performed is considered a beneficial practice.

In this article, We will explore the process of testing exception handling with JUnit5. 

For asserting the type of exception and exception message, JUnit provides a static method "Assertions.assertThrows".

Let us examine all the possible scenarios that can be tested using "Assertions.assertThrows"

2. Example

2.1 Class under Test

The ArithmeticOperators class has a division method that throws an exception if the second argument is zero(0). In the upcoming section, we will test this method using Assertions.assertThrows()
package com.thebackendpro.junit5.exceptionstesting;

public class ArithmeticOperators {

    public int division(int a, int b) {
        if(b == 0) {
            throw new ArithmeticException("Cannot divide a number by 0");
        }
        return a/b;
    }
}
  

2.2 JUnit tests using Assertions.assertThrows

The ArithmeticOperatorsTest class tests the division method. The ArithmeticOperators.division() method throws ArithmeticExcpetion as the 2nd argument is 0. 

The test method asserts the exception as well as the message using Assertions.assertThrows()

package com.thebackendpro.junit5.exceptionstesting;

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

public class ArithmeticOperatorsTest {
    @Test
    public void divisionTest() {
        ArithmeticOperators arithmeticOperators = new ArithmeticOperators();
        ArithmeticException arithmeticException = Assertions.assertThrows(ArithmeticException.class, () -> {
            arithmeticOperators.division(5, 0);
        });
        Assertions.assertEquals("Cannot divide a number by 0", arithmeticException.getMessage());
    }
}

3. Syntax

The method Assertions.assertThrows() has multiple overloaded versions. It asserts that the execution of the supplied lambda expression throws an exception matched expectedType. 

It fails when no exception or a different type of exception is thrown. 

public static <T extends Throwable> T assertThrows(Class<T> expectedType, Executable executable)
  • expectedType - The test method is expected to raise an exception of this type. 
  • executable - Lambda expression that invokes the method under test. 

public static <T extends Throwable> T assertThrows(Class<T> expectedType, Executable executable, String
    message)
  • expectedType - The test method is expected to raise an exception of this type. 
  • executable - Lambda expression that invokes the method under test. 
  • message - When failed the supplied message is displayed. It helps the developer to quickly identify the reason for test failure. 

public static <T extends Throwable> T assertThrows(Class<T> expectedType, Executable
    executable,Supplier<String> messageSupplier) 
  • expectedType - The test method is expected to raise an exception of this type. 
  • executable - Lambda expression that invokes the method under test. 
  • messageSupplier - When failed the supplier is executed to retrieve the failure message and the message is displayed. It helps the developer to quickly identify the reason for test failure. 

4. Further Examples

4.1 When Expected Exception is Thrown


package com.thebackendpro.junit5.exceptionstesting;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
            
public class ArithmeticOperatorsTest {
    @Test
    public void divisionTest() {
        ArithmeticOperators arithmeticOperators = new ArithmeticOperators();
        ArithmeticException arithmeticException = Assertions.assertThrows(ArithmeticException.class,
                           () -> arithmeticOperators.division(5, 0));
        Assertions.assertEquals("Cannot divide a number by 0", arithmeticException.getMessage());
    }
}

Output



4.2 When No Exception is Thrown

package com.thebackendpro.junit5.exceptionstesting;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
        
public class ArithmeticOperatorsTest {
    @Test
    public void divisionTest() {
        ArithmeticOperators arithmeticOperators = new ArithmeticOperators();
        ArithmeticException arithmeticException = Assertions.assertThrows(ArithmeticException.class,
                        () -> arithmeticOperators.division(5, 1), "Failed due to no exception is thrown");
        Assertions.assertEquals("Cannot divide a number by 0", arithmeticException.getMessage());
    }
}

Output



Refer to all the code examples used in this article at GitHub

Tags

#buttons=(Accept !) #days=(20)

Our website uses cookies to enhance your experience. Check Now
Accept !