DEV Community

realNameHidden
realNameHidden

Posted on

thenThrow() method in Mockito example

Scenario: Mocking a Service to Throw an Exception for Testing Error Handling in a Controller

1. Spring Boot Application Code

Employee.java

package com.example.demo.model;

public class Employee {
    private String id;
    private String name;

    // Constructors, Getters, and Setters
    public Employee(String id, String name) {
        this.id = id;
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Enter fullscreen mode Exit fullscreen mode

EmployeeNotFoundException.java (Custom Exception)

package com.example.demo.exception;

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

Enter fullscreen mode Exit fullscreen mode

EmployeeService.java

package com.example.demo.service;

import com.example.demo.exception.EmployeeNotFoundException;
import com.example.demo.model.Employee;
import org.springframework.stereotype.Service;

@Service
public class EmployeeService {
    public Employee getEmployeeById(String id) {
        // Simulating an exception when employee is not found
        if ("0".equals(id)) {
            throw new EmployeeNotFoundException("Employee not found with id: " + id);
        }
        return new Employee(id, "John Doe");
    }
}

Enter fullscreen mode Exit fullscreen mode

EmployeeController.java

package com.example.demo.controller;

import com.example.demo.exception.EmployeeNotFoundException;
import com.example.demo.model.Employee;
import com.example.demo.service.EmployeeService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/employees")
public class EmployeeController {
    private final EmployeeService employeeService;

    public EmployeeController(EmployeeService employeeService) {
        this.employeeService = employeeService;
    }

    @GetMapping("/{id}")
    public ResponseEntity<Employee> getEmployee(@PathVariable String id) {
        Employee employee = employeeService.getEmployeeById(id);
        return ResponseEntity.ok(employee);
    }

    // Global Exception Handling
    @ExceptionHandler(EmployeeNotFoundException.class)
    public ResponseEntity<String> handleEmployeeNotFoundException(EmployeeNotFoundException ex) {
        return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
    }
}

Enter fullscreen mode Exit fullscreen mode
  1. Unit Test Using thenThrow() EmployeeControllerTest.java
package com.example.demo.controller;

import com.example.demo.exception.EmployeeNotFoundException;
import com.example.demo.model.Employee;
import com.example.demo.service.EmployeeService;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.http.ResponseEntity;

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

class EmployeeControllerTest {

    @Mock
    private EmployeeService employeeService;

    @InjectMocks
    private EmployeeController employeeController;

    public EmployeeControllerTest() {
        MockitoAnnotations.openMocks(this); // Initialize mocks
    }

    @Test
    void testGetEmployee_Success() {
        // Arrange: Stub service method to return an Employee
        when(employeeService.getEmployeeById("1")).thenReturn(new Employee("1", "John Doe"));

        // Act: Call the controller method
        ResponseEntity<Employee> response = employeeController.getEmployee("1");

        // Assert: Verify response is correct
        assertNotNull(response);
        assertEquals(200, response.getStatusCodeValue());
        assertEquals("John Doe", response.getBody().getName());

        // Verify the service method was called once
        verify(employeeService, times(1)).getEmployeeById("1");
    }

    @Test
    void testGetEmployee_ThrowsException() {
        // Arrange: Stub the service method to throw an exception
        when(employeeService.getEmployeeById("0")).thenThrow(new EmployeeNotFoundException("Employee not found with id: 0"));

        // Act & Assert: Verify that the exception is handled correctly
        Exception exception = assertThrows(EmployeeNotFoundException.class, () -> {
            employeeController.getEmployee("0");
        });

        assertEquals("Employee not found with id: 0", exception.getMessage());

        // Verify the service method was called once
        verify(employeeService, times(1)).getEmployeeById("0");
    }
}

Enter fullscreen mode Exit fullscreen mode

Explanation

Using thenThrow()

when(employeeService.getEmployeeById("0")).thenThrow(new EmployeeNotFoundException("Employee not found with id: 0"))

This stubs the service method to throw EmployeeNotFoundException when called with "0".

Unit Test Steps

  1. First Test Case (testGetEmployee_Success)

Mocks a successful response using thenReturn().

Calls the controller and asserts the response.

  1. Second Test Case (testGetEmployee_ThrowsException)

Uses thenThrow() to simulate an exception.

Calls the controller method and asserts that the exception is thrown.

Uses assertThrows() to verify exception handling.

Advantages of thenThrow()

Simulates real-world error handling without modifying the actual service.

Helps in testing exception scenarios like database errors, missing data, API failures, etc.
Ensures that the application responds correctly when errors occur.

Conclusion

Using Mockito’s thenThrow(), you can efficiently test exception handling scenarios in a Spring Boot application without executing the actual logic.

Top comments (0)