Mockito thenThrow Method

The thenThrow method in the Mockito framework is used to configure mock objects to throw exceptions when specific methods are called. This is particularly useful for testing how your code handles exceptions. The method belongs to the OngoingStubbing interface, which is used to configure the behavior of mock methods.

Table of Contents

  1. Introduction
  2. thenThrow Method Syntax
  3. Examples
    • Basic Usage with a Single Throwable Class
    • Setting Consecutive Throwable Classes
    • Setting Consecutive Throwable Objects
  4. Real-World Use Case
  5. Conclusion

Introduction

Mockito is a popular library in Java for creating and managing mock objects. The thenThrow method, which belongs to the OngoingStubbing interface, allows you to specify exceptions that should be thrown when a method is called. This can be useful for testing error handling in your code.

thenThrow Method Syntax

Throwing a Single Throwable Class

import org.mockito.stubbing.OngoingStubbing;

OngoingStubbing<T> thenThrow(Class<? extends Throwable> throwableType)

Sets a Throwable type to be thrown when the method is called.

Throwing Consecutive Throwable Classes

import org.mockito.stubbing.OngoingStubbing;

OngoingStubbing<T> thenThrow(Class<? extends Throwable> toBeThrown, Class<? extends Throwable>... nextToBeThrown)

Sets Throwable classes to be thrown when the method is called.

Throwing Consecutive Throwable Objects

import org.mockito.stubbing.OngoingStubbing;

OngoingStubbing<T> thenThrow(Throwable... throwables)

Sets Throwable objects to be thrown when the method is called.

Parameters:

  • throwableType: The Throwable class to be thrown.
  • toBeThrown: The first Throwable class to be thrown.
  • nextToBeThrown: Additional Throwable classes to be thrown consecutively.
  • throwables: Throwable objects to be thrown consecutively.

Returns:

  • An OngoingStubbing object that allows further configuration of the stubbed method.

Examples

Basic Usage with a Single Throwable Class

Set a single Throwable class to be thrown for a stubbed method.

import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;

public class BasicThenThrowTest {
    @Test
    void testThenThrow() {
        UserService mockUserService = mock(UserService.class);

        // Set a Throwable class to be thrown
        when(mockUserService.getUserDetails(anyString())).thenThrow(IllegalArgumentException.class);

        // Call the method and verify the exception
        try {
            mockUserService.getUserDetails("123");
        } catch (IllegalArgumentException e) {
            assertEquals(IllegalArgumentException.class, e.getClass());
        }
    }
}

class UserService {
    public String getUserDetails(String userId) {
        return "Real user details for " + userId;
    }
}

Setting Consecutive Throwable Classes

Set consecutive Throwable classes to be thrown for a stubbed method.

import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;

public class ConsecutiveThenThrowTest {
    @Test
    void testConsecutiveThenThrow() {
        UserService mockUserService = mock(UserService.class);

        // Set consecutive Throwable classes to be thrown
        when(mockUserService.getUserDetails(anyString())).thenThrow(IllegalArgumentException.class, NullPointerException.class);

        // Call the method multiple times and verify the exceptions
        try {
            mockUserService.getUserDetails("123");
        } catch (IllegalArgumentException e) {
            assertEquals(IllegalArgumentException.class, e.getClass());
        }

        try {
            mockUserService.getUserDetails("123");
        } catch (NullPointerException e) {
            assertEquals(NullPointerException.class, e.getClass());
        }
    }
}

class UserService {
    public String getUserDetails(String userId) {
        return "Real user details for " + userId;
    }
}

Setting Consecutive Throwable Objects

Set consecutive Throwable objects to be thrown for a stubbed method.

import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;

public class ConsecutiveThenThrowObjectsTest {
    @Test
    void testConsecutiveThenThrowObjects() {
        UserService mockUserService = mock(UserService.class);

        // Set consecutive Throwable objects to be thrown
        when(mockUserService.getUserDetails(anyString())).thenThrow(new IllegalArgumentException("Invalid argument"), new NullPointerException("Null pointer"));

        // Call the method multiple times and verify the exceptions
        try {
            mockUserService.getUserDetails("123");
        } catch (IllegalArgumentException e) {
            assertEquals("Invalid argument", e.getMessage());
        }

        try {
            mockUserService.getUserDetails("123");
        } catch (NullPointerException e) {
            assertEquals("Null pointer", e.getMessage());
        }
    }
}

class UserService {
    public String getUserDetails(String userId) {
        return "Real user details for " + userId;
    }
}

Real-World Use Case

Testing Error Handling in Services

In a real-world scenario, you might need to test how your service handles exceptions. The thenThrow method allows you to simulate various error conditions and verify that your service responds appropriately.

import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

interface PaymentService {
    void processPayment(String orderId) throws Exception;
}

class PaymentServiceImpl implements PaymentService {
    public void processPayment(String orderId) {
        // Real implementation
    }
}

public class PaymentServiceTest {
    @Test
    void testProcessPayment() {
        PaymentService mockPaymentService = mock(PaymentService.class);

        // Set Throwable classes to be thrown
        doThrow(new IllegalStateException("Service unavailable")).when(mockPaymentService).processPayment("123");

        // Call the method and verify the exception
        Exception exception = assertThrows(IllegalStateException.class, () -> {
            mockPaymentService.processPayment("123");
        });
        assertEquals("Service unavailable", exception.getMessage());
    }
}

In this example, the PaymentServiceTest class uses Mockito’s thenThrow method to simulate an IllegalStateException when the processPayment method is called. This allows the test to verify that the service correctly handles the exception.

Conclusion

The thenThrow method in Mockito is used for configuring mock objects to throw exceptions. By using thenThrow, you can specify exceptions that should be thrown when a method is called, allowing you to test how your code handles various error conditions. This helps ensure that your tests are accurate and comprehensive, allowing you to validate both normal and exceptional behavior.

Leave a Comment

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

Scroll to Top