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

SpringBoot中Mockito注入服务时无法Mock依赖服务的JUnit测试问题

解决SpringBoot服务测试中Mock失效的问题

这种情况我之前调试服务测试时也碰到过,大概率是Mock对象的注入逻辑或者依赖初始化方式出了问题,咱们一步步排查解决:

1. 先确认Mock框架的注解配置是否正确

如果你用的是Mockito,要确保测试类里的Mock对象能正确注入到被测试的EmployeeService中:

  • 对于JUnit 5,测试类要加上@ExtendWith(MockitoExtension.class)来启用Mockito的扩展支持
  • 对RoleService和GroupService用@Mock标记为Mock对象
  • 对EmployeeService用@InjectMocks标记,让Mockito自动把Mock对象注入进去

举个正确的测试类示例:

@ExtendWith(MockitoExtension.class)
public class EmployeeServiceTest {
    @Mock
    private RoleService roleService;
    @Mock
    private GroupService groupService;
    
    @InjectMocks
    private EmployeeService employeeService;

    @Test
    void testCreateEmp() {
        // 构造测试用的员工对象
        Employee testEmp = new Employee();
        testEmp.setEmpId("1001");
        
        // 打桩:指定Mock方法的行为(这里模拟无返回值的调用)
        doNothing().when(roleService).createRole(any(Employee.class));
        doNothing().when(groupService).createGroup(any(Employee.class));
        
        // 执行被测试方法
        employeeService.createEmp(testEmp);
        
        // 验证Mock方法是否被正确调用
        verify(roleService, times(1)).createRole(testEmp);
        verify(groupService, times(1)).createGroup(testEmp);
    }
}

2. 检查被测试服务的依赖注入方式

如果你的EmployeeService里是直接用new关键字创建RoleService或GroupService的实例,那Mock对象根本没法替换掉真实实例,自然会执行真实方法:
❌ 错误写法:

@Service
public class EmployeeService {
    // 直接new实例,Mock无法生效
    private RoleService roleService = new RoleServiceImpl();

    public void createEmp(Employee emp) {
        roleService.createRole(emp);
        // ...
    }
}

✅ 正确写法:用构造器注入(Spring官方推荐)或者@Autowired注入依赖:

@Service
public class EmployeeService {
    private final RoleService roleService;
    private final GroupService groupService;

    // 构造器注入,方便测试时替换依赖
    public EmployeeService(RoleService roleService, GroupService groupService) {
        this.roleService = roleService;
        this.groupService = groupService;
    }

    public void createEmp(Employee emp) {
        roleService.createRole(emp);
        groupService.createGroup(emp);
    }
}

3. 如果你用了@SpringBootTest,要替换Spring上下文里的Bean

如果你的测试类加载了完整的Spring上下文(比如用了@SpringBootTest),单纯的@Mock注解不会替换掉上下文里的真实Bean,这时候要改用@MockBean来替换:

@SpringBootTest
public class EmployeeServiceIntegrationTest {
    @MockBean
    private RoleService roleService;
    @MockBean
    private GroupService groupService;
    
    @Autowired
    private EmployeeService employeeService;

    @Test
    void testCreateEmp() {
        doNothing().when(roleService).createRole(any(Employee.class));
        doNothing().when(groupService).createGroup(any(Employee.class));
        
        employeeService.createEmp(new Employee());
        
        // 验证Mock方法的调用情况
        verify(roleService).createRole(any());
    }
}

@MockBean会自动把Spring上下文中对应的真实服务替换成Mock对象,这样调用时就不会走真实逻辑了。

4. 检查Mock打桩的方法签名是否匹配

如果打桩时用的参数匹配器和实际调用的参数类型不匹配,Mock也会失效。比如createRole接收的是Employee类型,但你打桩时用了anyString(),这时候Mock不会生效,还是会执行真实方法。要确保参数匹配器和实际调用的参数一致,比如用any(Employee.class)或者具体的参数值。

总结

最常见的问题就是依赖初始化方式错误(直接new实例)或者Mock对象没有正确注入到被测试类,按照上面的步骤排查,应该就能解决Mock失效的问题了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 11:13:11