使用Mockito模拟HashMap方法时未得到预期返回值的问题求助
问题原因与解决办法
问题根源
你测试代码里定义的map1是测试类自己的静态Mock对象,和业务类中private static Map<String,Long> map1完全是两个独立的实例。业务方法执行时,始终使用的是自身类里初始化的空HashMap,所以不管你怎么mock测试类里的map1,都不会对业务逻辑产生影响,最终返回0L。
解决办法
方法一:用PowerMock mock静态私有成员(适合无法修改业务代码的场景)
PowerMock可以突破普通Mockito的限制,直接mock类的静态私有成员:
- 先引入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>
- 修改测试类:
@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); } }
方法二:重构业务代码,改用依赖注入(更推荐)
静态成员会导致代码耦合度高、可测试性差,重构为依赖注入的方式能从根本上解决问题:
- 修改业务类代码:
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); } }
- 修改测试代码:
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
相关产品推荐
相关产品推荐

