You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Mockito测试Spring中的Controller方法?

我来帮你搞定用Mockito测试这个Spring Controller的addAccount方法!首先,咱们得明确这个方法的核心逻辑分支:参数校验失败、用户名已存在、账号正常创建成功,这几个场景都得覆盖到。我会用Spring Boot Test结合Mockito来写测试,这样能更贴近真实的运行环境。

前置依赖

首先确保你的项目依赖里包含Spring Boot Test(它已经内置了Mockito和MockMvc,不用额外引入):

<!-- Maven示例 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
测试类基础结构

先创建对应的测试类,用@WebMvcTest只加载Controller层Bean,配合@MockBean模拟依赖的accountRepository和bCryptPasswordEncoder:

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 static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

// 替换成你的实际Controller类名
@WebMvcTest(AccountController.class)
public class AccountControllerTest {

    @Autowired
    private MockMvc mockMvc; // 用来模拟HTTP请求

    @MockBean
    private AccountRepository accountRepository; // 模拟Repository依赖

    @MockBean
    private BCryptPasswordEncoder bCryptPasswordEncoder; // 模拟密码加密器
}
分场景测试示例

1. 测试参数不合法的情况

当传入的Account为null、userName为空或userPass为空时,方法应该返回参数错误响应:

子场景:Account对象为null

@Test
public void addAccount_WhenAccountIsNull_ReturnsBadRequest() throws Exception {
    mockMvc.perform(post("/add")
                    .contentType(MediaType.APPLICATION_JSON)
                    .content("null")) // 传入null的请求体
            .andExpect(status().isBadRequest());
}

子场景:userName为空

@Test
public void addAccount_WhenUserNameIsNull_ReturnsBadRequest() throws Exception {
    String invalidAccountJson = "{\"userName\": null, \"userPass\": \"123456\"}";

    mockMvc.perform(post("/add")
                    .contentType(MediaType.APPLICATION_JSON)
                    .content(invalidAccountJson))
            .andExpect(status().isBadRequest());
}

2. 测试用户名已存在的情况

当accountRepository.countUserName()返回大于0的数值时,方法应该返回BAD_REQUEST和"Account":

@Test
public void addAccount_WhenUserNameExists_ReturnsBadRequest() throws Exception {
    String existingAccountJson = "{\"userName\": \"oldUser\", \"userPass\": \"123456\"}";

    // Mock用户名已存在的场景
    when(accountRepository.countUserName("oldUser")).thenReturn(1L);

    mockMvc.perform(post("/add")
                    .contentType(MediaType.APPLICATION_JSON)
                    .content(existingAccountJson))
            .andExpect(status().isBadRequest())
            .andExpect(content().string("Account")); // 验证返回内容

    // 确认Repository的方法确实被调用了一次
    verify(accountRepository, times(1)).countUserName("oldUser");
}

3. 测试账号添加成功的情况

当参数合法且用户名不存在时,会执行密码加密、保存账号,最终返回成功响应:

@Test
public void addAccount_WhenValidAccount_ReturnsSuccess() throws Exception {
    String validAccountJson = "{\"userName\": \"newUser\", \"userPass\": \"plainPwd\"}";
    String mockEncodedPwd = "encodedPwd123";

    // Mock用户名不存在
    when(accountRepository.countUserName("newUser")).thenReturn(0L);
    // Mock密码加密结果
    when(bCryptPasswordEncoder.encode("plainPwd")).thenReturn(mockEncodedPwd);
    // Mock账号保存操作(无返回值)
    doNothing().when(accountRepository).AccountSaveTo(any(Account.class));

    mockMvc.perform(post("/add")
                    .contentType(MediaType.APPLICATION_JSON)
                    .content(validAccountJson))
            .andExpect(status().isOk()); // 替换成你方法实际返回的成功状态码

    // 验证所有依赖方法都被正确调用
    verify(accountRepository, times(1)).countUserName("newUser");
    verify(bCryptPasswordEncoder, times(1)).encode("plainPwd");
    verify(accountRepository, times(1)).AccountSaveTo(any(Account.class));
}
小提示
  • 原方法里的bCryptPasswordEncoder.encod()应该是笔误,正确方法名是encode(),测试时要对应上;
  • 可以用ObjectMapper序列化Account对象生成JSON,避免手动写JSON出错:
    ObjectMapper objectMapper = new ObjectMapper();
    String accountJson = objectMapper.writeValueAsString(new Account("newUser", "plainPwd"));
    

内容的提问来源于stack exchange,提问作者martine

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:50:56