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

Mockito.when().thenReturn()与doReturn().when()未返回指定模拟值问题

Mockito Mock 未返回指定值的问题排查与解决

嘿,这个问题我太熟了——这是Mockito新手常踩的一个坑!咱们先看看你代码里的核心问题:

问题根源:Mock实例不匹配

你同时使用了@Mock注解和手动Mockito.mock(UserRepository.class)创建对象,而且在initMocks方法里重新给mockUserRepository赋值了。这会导致两个关键问题:

  1. @InjectMocks会把**@Mock注解创建的那个UserRepository实例**注入到userService里
  2. 你后续调用Mockito.doReturn()和Mockito.when()时,操作的是手动mock出来的新实例

这两个实例完全是不同的对象,所以你设置的mock返回值自然不会生效——userService调用的是另一个没被配置过的mock对象!

解决方案:二选一,保持Mock实例一致

方案1:只用注解方式(推荐)

删掉手动mock的代码,让Mockito的注解机制帮你处理实例创建和注入:

@InjectMocks 
private UserServiceImpl userService; 

@Mock 
private UserRepository mockUserRepository; 

@Before 
public void initMocks() throws Exception { 
    // 只需要初始化注解生成的mock对象
    MockitoAnnotations.initMocks(this); 
    // 删掉这行多余的代码:mockUserRepository = Mockito.mock(UserRepository.class); 
} 

@Test 
public void testCreateUser() { 
    User user = createUser(); 
    // 现在操作的mock和userService里的是同一个了
    Mockito.doReturn(user).when(mockUserRepository).findByEmail(user.getEmail()); 
    Mockito.when(mockUserRepository.save(user)).thenReturn(user); 
    
    // 执行测试并断言
    User createdUser = userService.createUser(user);
    assertEquals(user.getEmail(), createdUser.getEmail());
}

方案2:手动创建并注入Mock(适合需要更灵活控制的场景)

如果你不想用注解,那就完全手动管理mock实例和注入:

private UserServiceImpl userService; 
private UserRepository mockUserRepository; 

@Before 
public void initMocks() throws Exception { 
    // 手动创建mock
    mockUserRepository = Mockito.mock(UserRepository.class); 
    // 手动把mock注入到service(假设UserServiceImpl有对应的构造方法)
    userService = new UserServiceImpl(mockUserRepository); 
} 

@Test 
public void testCreateUser() { 
    User user = createUser(); 
    Mockito.doReturn(user).when(mockUserRepository).findByEmail(user.getEmail()); 
    Mockito.when(mockUserRepository.save(user)).thenReturn(user); 
    
    User createdUser = userService.createUser(user);
    assertEquals(user, createdUser);
}

额外优化:使用Mockito扩展简化代码

如果你用的是Mockito 2.2及以上版本,推荐用@ExtendWith(MockitoExtension.class)代替@Before里的初始化代码,更简洁:

@ExtendWith(MockitoExtension.class)
public class UserServiceImplTest {
    @InjectMocks 
    private UserServiceImpl userService; 

    @Mock 
    private UserRepository mockUserRepository; 

    // 不需要写@Before初始化方法了!

    @Test 
    public void testCreateUser() { 
        User user = createUser(); 
        Mockito.doReturn(user).when(mockUserRepository).findByEmail(user.getEmail()); 
        Mockito.when(mockUserRepository.save(user)).thenReturn(user); 
        
        User createdUser = userService.createUser(user);
        assertEquals(user.getEmail(), createdUser.getEmail());
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:16:41