自学内容网 自学内容网

springboot mockmvc 单元测试

在 Spring Boot 中使用 MockMvc 进行单元测试是一种非常有效的方法,可以测试控制器(Controller)层而不启动整个应用程序上下文。通过结合 Mockito 和 @WebMvcTest 注解,可以轻松地模拟依赖服务并测试 HTTP 请求和响应。

示例:Spring Boot MockMvc 单元测试

假设有一个简单的 UserController 依赖于 UserService

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

    private final UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        User user = userService.findById(id);
        if (user != null) {
            return ResponseEntity.ok(user);
        } else {
            return ResponseEntity.notFound().build();
        }
    }
}
编写测试类

接下来是 UserControllerTest 类,它展示了如何使用 MockMvc@WebMvcTest 来进行单元测试:

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;

import com.example.demo.model.User;
import com.example.demo.service.UserService;

@WebMvcTest(controllers = UserController.class)
public class UserControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private UserService userService;

    @Test
    void shouldReturnDefaultMessage() throws Exception {
        // Arrange
        Long userId = 1L;
        User mockUser = new User(userId, "John Doe");

        // 使用 Mockito 模拟行为
        when(userService.findById(userId)).thenReturn(mockUser);

        // Act & Assert
        mockMvc.perform(get("/api/users/{id}", userId)
                .accept(MediaType.APPLICATION_JSON))
               .andExpect(status().isOk())
               .andExpect(jsonPath("$.name").value("John Doe"));

        // 验证 userService.findById 被调用了一次,并且参数为 1L
        verify(userService, times(1)).findById(userId);
    }
}

在这个例子中:

  • @WebMvcTest 注解告诉 Spring Boot 只加载与 Web 层相关的组件(例如控制器),而不会加载整个应用程序上下文。
  • @Autowired MockMvc 提供了用于执行和验证 HTTP 请求的入口点。
  • @MockBean 创建了一个 UserService 的模拟实例,并将其添加到应用上下文中。这使得我们可以定义它的行为,而不需要真实的服务实现。
  • when() 方法用于指定模拟对象的行为,即当调用 userService.findById(1L) 时应该返回 mockUser
  • mockMvc.perform() 发起 HTTP GET 请求,andExpect() 方法链用来验证响应的状态码和内容。
  • verify() 确保 userService.findById 方法被正确调用。

测试无返回值的方法

如果你需要测试一个没有返回值的方法,比如 POST 或 DELETE 请求,你可以使用 doNothing(), doThrow(), 或者 doAnswer() 来定义模拟行为。例如:

@Test
void testDeleteUser() throws Exception {
    Long userId = 1L;

    // 使用 doNothing() 因为 delete 方法是 void
    doNothing().when(userService).deleteById(userId);

    mockMvc.perform(delete("/api/users/{id}", userId))
           .andExpect(status().isNoContent());

    verify(userService, times(1)).deleteById(userId);
}

总结

  • 使用 @WebMvcTest 和 MockMvc 可以有效地测试 Spring Boot 应用程序中的控制器。
  • @MockBean 用于创建模拟的依赖项,如服务层或数据访问层。
  • when() 和 do*() 方法用于定义模拟对象的行为。
  • mockMvc.perform() 和 andExpect() 用于发起请求并验证响应。

原文地址:https://blog.csdn.net/xuTao667/article/details/144352356

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!