Testing Spring Boot REST Controller with Mockito
Testing Spring Boot REST Controller with Mockito

When developing a Spring Boot application, ensuring that your REST controllers function as expected is crucial. Mockito is a powerful mocking framework that helps in creating unit tests for your Spring Boot application. This blog will guide you through testing a Spring Boot REST controller using Mockito, complete with a class example, test example, and a complete flow so let’s do Testing Spring Boot REST Controller with Mockito!

Table of Contents

  1. Introduction to Mockito
  2. Setting Up Your Spring Boot Project
  3. Creating a REST Controller
  4. Writing Unit Tests with Mockito
  5. Conclusion

1. Introduction to Mockito

Mockito is a popular mocking framework for Java applications. It allows you to create mock objects and define their behavior, making it easier to isolate and test individual components of your application.

2. Setting Up Your Spring Boot Project

Ensure you have the following dependencies in your pom.xml file for Spring Boot, Mockito, and JUnit:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-core</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

3. Creating a REST Controller

Let’s create a simple REST controller for managing a list of users.

UserController.java

package com.example.demo.controller;

import com.example.demo.model.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping
    public List<User> getAllUsers() {
        return userService.getAllUsers();
    }

    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        User user = userService.getUserById(id);
        return ResponseEntity.ok(user);
    }

    @PostMapping
    public User createUser(@RequestBody User user) {
        return userService.createUser(user);
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        userService.deleteUser(id);
        return ResponseEntity.noContent().build();
    }
}

4. Writing Unit Tests with Mockito

To test the UserController, we will mock the UserService and define its behavior.

UserControllerTest.java

package com.example.demo.controller;

import com.example.demo.model.User;
import com.example.demo.service.UserService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import java.util.Arrays;
import java.util.List;

import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

import org.junit.jupiter.api.extension.ExtendWith;

@ExtendWith(MockitoExtension.class)
public class UserControllerTest {

    @InjectMocks
    private UserController userController;

    @Mock
    private UserService userService;

    private MockMvc mockMvc;

    @BeforeEach
    public void setUp() {
        mockMvc = MockMvcBuilders.standaloneSetup(userController).build();
    }

    @Test
    public void testGetAllUsers() throws Exception {
        List<User> users = Arrays.asList(new User(1L, "John Doe"), new User(2L, "Jane Doe"));
        when(userService.getAllUsers()).thenReturn(users);

        mockMvc.perform(get("/users"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$[0].name").value("John Doe"))
                .andExpect(jsonPath("$[1].name").value("Jane Doe"));
    }

    @Test
    public void testGetUserById() throws Exception {
        User user = new User(1L, "John Doe");
        when(userService.getUserById(1L)).thenReturn(user);

        mockMvc.perform(get("/users/1"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.name").value("John Doe"));
    }

    @Test
    public void testCreateUser() throws Exception {
        User user = new User(1L, "John Doe");
        when(userService.createUser(user)).thenReturn(user);

        mockMvc.perform(post("/users")
                .contentType(MediaType.APPLICATION_JSON)
                .content("{\"id\":1,\"name\":\"John Doe\"}"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.name").value("John Doe"));
    }

    @Test
    public void testDeleteUser() throws Exception {
        mockMvc.perform(delete("/users/1"))
                .andExpect(status().isNoContent());
    }
}

5. Conclusion

Testing Spring Boot REST controllers with Mockito is a powerful way to ensure your application functions correctly. By mocking dependencies, you can isolate and test individual components effectively. The complete flow includes setting up the project, creating a REST controller, writing unit tests, and running the tests. With these steps, you can achieve a high level of confidence in your application’s correctness.

References

Leave a Reply

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