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

使用Mockito模拟HashMap方法时未得到预期返回值的问题求助

问题原因与解决办法

问题根源

你测试代码里定义的map1是测试类自己的静态Mock对象,和业务类中private static Map<String,Long> map1完全是两个独立的实例。业务方法执行时,始终使用的是自身类里初始化的空HashMap,所以不管你怎么mock测试类里的map1,都不会对业务逻辑产生影响,最终返回0L。

解决办法

方法一:用PowerMock mock静态私有成员(适合无法修改业务代码的场景)

PowerMock可以突破普通Mockito的限制,直接mock类的静态私有成员:

  1. 先引入PowerMock依赖(以Maven为例):
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>2.0.9</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito2</artifactId>
    <version>2.0.9</version>
    <scope>test</scope>
</dependency>
  1. 修改测试类:
@RunWith(PowerMockRunner.class)
@PrepareForTest(业务类.class) // 替换成你的业务类实际类名
public class 业务类测试 {

    private Map<String,Long> mockMap = mock(Map.class); 

    @Test
    public void testfoo(){
        // 将业务类的静态map1替换为mock对象
        Whitebox.setInternalState(业务类.class, "map1", mockMap);
        
        when(mockMap.containsKey("test")).thenReturn(true);
        when(mockMap.get("test")).thenReturn(2L);
        
        long value = 业务类.foo("test");
        Assert.assertEquals(2L, value);
    }
}

方法二:重构业务代码,改用依赖注入(更推荐)

静态成员会导致代码耦合度高、可测试性差,重构为依赖注入的方式能从根本上解决问题:

  1. 修改业务类代码:
public class 业务类 {
    private Map<String,Long> map1;

    // 通过构造方法注入map
    public 业务类(Map<String, Long> map1) {
        this.map1 = map1;
    }

    public long foo(final String test){
         if(!map1.containsKey(test)){
             return 0L;
         }
         return map1.get(test);
     }
}
  1. 修改测试代码:
public class 业务类测试 {
    private Map<String,Long> mockMap = mock(Map.class); 
    private 业务类 classUndertest;

    @Before
    public void setUp() {
        // 测试时传入mock的map实例
        classUndertest = new 业务类(mockMap);
    }

    @Test
    public void testfoo(){
        when(mockMap.containsKey("test")).thenReturn(true);
        when(mockMap.get("test")).thenReturn(2L);
        
        long value = classUndertest.foo("test");
        Assert.assertEquals(2L, value);
    }
}

为什么推荐依赖注入?

这种方式让业务类不再依赖静态成员,代码耦合度更低,不仅测试变得简单,后续维护和扩展也更灵活,符合面向对象的设计原则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 13:30:42