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

Mockito+JUnit4 Mock方法未生效:调用实际方法问题求助

问题:Mockito Mock对象失效,调用真实方法

我正在学习Mockito与JUnit4,现有UserService接口及其实现类UserServiceImpl,在UserInfoImpl类中调用了该接口的getUserInfo方法。尝试通过Mock UserServiceImpl来测试UserInfoImpl,但实际调用的是真实方法(已通过真实方法中的System.out验证),不清楚原因,请求技术支持。

相关代码

JUnit测试类

public class Junit4WithMockito {


    private UserInfoImpl userInfo;
    
    @Mock
    private UserService userService;
    
    @Before
    public void setUp() {
        
        System.out.println("Inside Setup");
        MockitoAnnotations.initMocks(this);
        
        
    }
    
    @Test
    public void testUserInfoImpl() throws InterruptedException {
        String cid="yu444";
        userInfo = new UserInfoImpl();
        userInfo.setUserService(userService);   
        when(userService.getUserInfo(cid)).thenReturn(new User("John Doe",33));
        Assert.assertEquals("Peter",userInfo.getUserInfo(cid).getUsername());
        
    }
    
}

UserInfoImpl类

public class UserInfoImpl implements UserInfo {

    private UserService userService;

    public UserService getUserService() {
        return userService;
    }

    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    @Override
    public User getUserInfo(String username) {

        try {
            userService = new UserServiceImpl();
            return userService.getUserInfo(username);
        } catch (InterruptedException e) {
            e.printStackTrace();
            return null;
        }
    }

}

UserServiceImpl类

public class UserServiceImpl implements UserService {

    @Override
    public User getUserInfo(String username) throws InterruptedException {

        System.out.println("Inside the actual Service");
        Thread.sleep(5000);
        return new User("John Doe",33);
    }

}

错误信息

JUnit错误截图

原因分析

核心问题出在UserInfoImpl的getUserInfo方法中:你在方法内部手动创建了UserServiceImpl实例,覆盖了通过setUserService注入的Mock对象。也就是说,测试代码中你先通过userInfo.setUserService(userService)把Mock对象注入到userInfo中,但当执行userInfo.getUserInfo(cid)时,方法内部的userService = new UserServiceImpl();语句直接替换掉了之前的Mock实例,导致实际调用的是真实服务类的方法。

解决方案

修改UserInfoImpl的getUserInfo方法,移除内部创建UserServiceImpl的代码,直接使用已注入的userService实例:

public class UserInfoImpl implements UserInfo {

    private UserService userService;

    public UserService getUserService() {
        return userService;
    }

    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    @Override
    public User getUserInfo(String username) {
        try {
            // 移除手动创建实例的代码,直接使用注入的userService
            return userService.getUserInfo(username);
        } catch (InterruptedException e) {
            e.printStackTrace();
            return null;
        }
    }

}

额外说明

修改后,测试类中的Mock配置会生效,但当前测试代码中的断言Assert.assertEquals("Peter",userInfo.getUserInfo(cid).getUsername())会失败,因为你预设的返回值是new User("John Doe",33),需要将断言调整为Assert.assertEquals("John Doe",userInfo.getUserInfo(cid).getUsername()),或者修改预设的返回值为new User("Peter",xxx)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 07:10:45