Mockito.when().thenReturn()与doReturn().when()未返回指定模拟值问题
Mockito Mock 未返回指定值的问题排查与解决
嘿,这个问题我太熟了——这是Mockito新手常踩的一个坑!咱们先看看你代码里的核心问题:
问题根源:Mock实例不匹配
你同时使用了@Mock注解和手动Mockito.mock(UserRepository.class)创建对象,而且在initMocks方法里重新给mockUserRepository赋值了。这会导致两个关键问题:
@InjectMocks会把**@Mock注解创建的那个UserRepository实例**注入到userService里- 你后续调用
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
相关产品推荐
相关产品推荐

