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

SpringBoot应用Java 8环境下单元测试使用Optional类返回Items列表时的类型转换异常排查与解决

问题排查与修复方案

从错误栈和你的测试代码来看,这个类型转换异常的根源是测试逻辑的错误,具体来说是你误用了Mockito的mock对象,并且错误地mock了被测试类的方法,而不是它的依赖组件。

错误原因分析

  1. 错误mock了被测试类的方法:
    你在测试里写了when(itemsService.addItemsService(itemListDto)).thenReturn(optionalList);,这完全不符合单元测试的逻辑——我们要测试的就是itemsService.addItemsService方法,不能提前mock它的返回值。这会导致Mockito内部的代理逻辑混乱,进而引发类型转换错误。

  2. 未正确mock依赖的ItemRepo的save方法:
    错误栈显示异常出现在ItemRepo.save方法,说明你的ItemsService.addItemsService方法内部在调用itemrepo.save(item)时,期望返回Items类型,但Mockito默认会为mock的方法返回null(或者错误的类型,如果之前有错误的mock设置),当代码尝试将返回值转换为Items时,就会抛出ClassCastException(这里看起来是意外返回了Optional类型,和你错误创建的optionalList有关)。

修复后的测试代码

下面是修正后的测试用例,我会标注关键修改点:

@ExtendWith(MockitoExtension.class)
public class ItemsMicroserviceApplicationServiceTests {
    @Mock
    ItemRepo itemrepo;
    @InjectMocks
    ItemsService itemsService = new ItemsService();
    List<Items> itemList;

    @Test
    void testaddItemsService() {
        // 1. 准备测试数据
        itemList = new ArrayList<>();
        Items item1 = new Items(1,"oneplus","good smartwatch",5999);
        Items item2 = new Items(2,"realme","decent buds",3999);
        itemList.add(item1);
        itemList.add(item2);
        ItemListDto itemListDto = new ItemListDto(itemList);

        // 2. 正确mock依赖的save方法:当调用repo.save时,返回传入的item(模拟保存成功的场景)
        when(itemrepo.save(any(Items.class))).thenAnswer(invocation -> invocation.getArgument(0));

        // 3. 调用被测试的方法
        Optional<List<Items>> result = itemsService.addItemsService(itemListDto);

        // 4. 添加有效的断言,验证结果和行为
        assertTrue(result.isPresent());
        assertEquals(itemList.size(), result.get().size());
        // 验证repo的save方法被调用了两次(对应两个item)
        verify(itemrepo, times(2)).save(any(Items.class));
    }
}

关键修改说明

  • 移除了错误的when(itemsService.addItemsService(...)):我们不再mock被测试方法的返回,而是让它真实执行,依赖mock的ItemRepo来完成逻辑。
  • 正确mockItemRepo.save方法:使用thenAnswer让save方法返回传入的对象(模拟保存成功的场景),这样service里的代码就能得到正确的Items类型返回值,避免类型转换错误。
  • 添加了有意义的断言:替换了无用的assertTrue(true),改为验证返回结果的正确性,以及验证依赖方法的调用次数,确保测试能真正验证业务逻辑。

额外检查点

如果修复后仍然有问题,建议检查ItemsService.addItemsService方法的第45行代码,确认它调用itemrepo.save后的处理逻辑是否正确,比如是否存在错误的类型转换(比如把Items当成Optional<Items>处理,或者反过来)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 15:32:37