JUnit assertThrowsExactly Method

The assertThrowsExactly method in JUnit is used to assert that a block of code throws exactly a specific type of exception. JUnit provides several overloaded versions of this method to handle different scenarios and to provide custom messages for test failures. This guide covers the basics of using the assertThrowsExactly method, including its syntax and examples of its different overloads.

Table of Contents

  1. Introduction
  2. assertThrowsExactly Method Syntax
  3. Examples
    • Basic Usage
    • Using a Custom Message
    • Using a Message Supplier
  4. Real-World Use Case
  5. Conclusion

Introduction

The assertThrowsExactly method in JUnit is an assertion method used to verify that a given block of code throws exactly a specific type of exception. If the code does not throw the expected exception or throws a subclass of the expected exception, the assertion fails, and the test is marked as failed. This method is fundamental for writing unit tests that check for the exact occurrence of exceptions in your code.

assertThrowsExactly Method Syntax

Here is the basic syntax of the assertThrowsExactly method with its different overloads:

// Asserts that the supplied executable throws exactly the expected type of exception and returns the exception
static <T extends Throwable> T assertThrowsExactly(Class<T> expectedType, Executable executable);

// Asserts that the supplied executable throws exactly the expected type of exception and returns the exception with a custom message
static <T extends Throwable> T assertThrowsExactly(Class<T> expectedType, Executable executable, String message);

// Asserts that the supplied executable throws exactly the expected type of exception and returns the exception with a custom message supplier
static <T extends Throwable> T assertThrowsExactly(Class<T> expectedType, Executable executable, Supplier<String> messageSupplier);

Parameters:

  • expectedType: The expected type of the exception.
  • executable: The block of code to be executed.
  • message: Optional. A custom message to display if the assertion fails.
  • messageSupplier: Optional. A supplier that provides a custom message to display if the assertion fails.

Returns:

  • The exception thrown by the executable if it matches the expected type.

Examples

Basic Usage

Verify that a block of code throws exactly a specific type of exception.

Example

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

public class ExceptionTest {
    @Test
    void testThrowsExactlyException() {
        assertThrowsExactly(IllegalArgumentException.class, () -> {
            throw new IllegalArgumentException("Invalid argument");
        });
    }
}

Using a Custom Message

Include a custom message to display if the assertion fails.

Example

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

public class CustomMessageTest {
    @Test
    void testThrowsExactlyExceptionWithMessage() {
        assertThrowsExactly(IllegalArgumentException.class, () -> {
            throw new IllegalArgumentException("Invalid argument");
        }, "Expected IllegalArgumentException to be thrown exactly");
    }
}

Using a Message Supplier

Use a message supplier to lazily generate a custom message if the assertion fails.

Example

import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
import org.junit.jupiter.api.Test;
import java.util.function.Supplier;

public class MessageSupplierTest {
    @Test
    void testThrowsExactlyExceptionWithMessageSupplier() {
        Supplier<String> messageSupplier = () -> "Expected IllegalArgumentException to be thrown exactly";
        assertThrowsExactly(IllegalArgumentException.class, () -> {
            throw new IllegalArgumentException("Invalid argument");
        }, messageSupplier);
    }
}

Real-World Use Case

Testing a UserService Class

A common use case for assertThrowsExactly is testing methods that are expected to throw exactly a specific type of exception in a UserService class. For example, verifying that a method throws exactly a UserNotFoundException when a user is not found.

Class Under Test – BookService

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

public class UserService {
    public User findUserById(int id) {
        if (id != 1) {
            throw new UserNotFoundException("User not found");
        }
        return new User("John Doe");
    }
}

class User {
    private String name;

    public User(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

Test Class – UserServiceTest

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

public class UserServiceTest {
    private final UserService userService = new UserService();

    @Test
    void testFindUserByIdThrowsExactlyException() {
        assertThrowsExactly(UserNotFoundException.class, () -> {
            userService.findUserById(2);
        }, "Expected UserNotFoundException to be thrown exactly");
    }

    @Test
    void testFindUserByIdThrowsExactlyExceptionWithMessageSupplier() {
        Supplier<String> messageSupplier = () -> "Expected UserNotFoundException to be thrown exactly";
        assertThrowsExactly(UserNotFoundException.class, () -> {
            userService.findUserById(2);
        }, messageSupplier);
    }
}

In this example, the UserServiceTest class tests the findUserById method of the UserService class using assertThrowsExactly. It includes tests to ensure that the method throws exactly a UserNotFoundException when a user with a given ID is not found.

Conclusion

The assertThrowsExactly method in JUnit is used for verifying that a given block of code throws exactly a specific type of exception in your tests. By using assertThrowsExactly and its various overloads, you can ensure that your tests provide clear feedback when exceptions are not thrown as expected. Understanding and using the assertThrowsExactly method effectively is crucial for developing robust and maintainable Java applications.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top