Spring Boot下JUnit测试HashMap containsKey断言失败如何解决
问题根因
你当前的测试逻辑存在3个核心错误:
- 你将
cache声明为@MockMockito模拟对象,模拟对象的所有方法默认都不会执行真实逻辑,调用put方法不会真的存储键值对,调用isEmpty()/containsKey()也只会返回Mockito的默认值(boolean类型默认返回false),这也是你assertFalse(cache.isEmpty())误判通过的原因。 - 测试代码中调用
loadFromDB()用了类名调用,这是实例方法应该用注入的employeeService实例调用,同时@BeforeEach里重复初始化employeeService属于冗余操作,@InjectMocks已经自动完成依赖注入。 - 如果业务代码中实际存入缓存的key和你断言的key不匹配,也会触发断言错误,需要确认业务逻辑里
put操作的key和测试校验的key一致。
解决方案
方案1:使用真实HashMap作为缓存(推荐)
缓存本身是无外部依赖的简单容器,直接用真实实例测试更符合实际运行场景,能直接验证存储结果:
@Mock private EmployeeRepository employeeRepo; // 不用@Mock注解,直接初始化真实HashMap实例 private Map<String, Employee> cache = new HashMap<>(); @InjectMocks private EmployeeService employeeService; @BeforeEach public void setUp() throws Exception { MockitoAnnotations.initMocks(this); // 不需要手动new EmployeeService,@InjectMocks已经自动注入上面的两个依赖 } @Test public void shouldLoadDataFromDBtoCache(){ when(employeeRepo.findActiveEmployee()).thenReturn(buildDataFromDB()); // 用实例调用方法,不能用类名调用 employeeService.loadFromDB(); // 现在cache是真实对象,所有状态断言都能正常生效 Assertions.assertFalse(cache.isEmpty()); Assertions.assertTrue(cache.containsKey("123")); // 其他你需要的key校验逻辑 }
方案2:继续使用Mock对象,验证方法调用行为
如果你坚持用Mock对象,不需要校验缓存状态,改为验证put方法有没有被正确调用即可:
@Mock private EmployeeRepository employeeRepo; @Mock private Map<String, Employee> cache; @InjectMocks private EmployeeService employeeService; @BeforeEach public void setUp() throws Exception { MockitoAnnotations.initMocks(this); } @Test public void shouldLoadDataFromDBtoCache(){ when(employeeRepo.findActiveEmployee()).thenReturn(buildDataFromDB()); Employee expectedEmp = buildDataFromDB(); // 你预期会存入缓存的Employee对象 employeeService.loadFromDB(); // 验证cache的put方法被调用了1次,参数和预期完全一致 Mockito.verify(cache, Mockito.times(1)).put("123", expectedEmp); // 不需要校验isEmpty或containsKey,因为Mock对象没有真实存储逻辑 }
内容的提问来源于stack exchange,提问作者ppb
相关产品推荐
相关产品推荐

