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

如何在SpringBootTest中用JUnit和Mockito模拟List场景下的ModelMapper?

解决JUnit+Mockito中ModelMapper处理列表时返回值被覆盖的问题

问题场景

你通过ModelMapper将数据库查询到的EmployeeEntity列表映射为EmployeeInfoPojo列表返回:

employeeList = employeeRepository.findAll();
employeeListPojos = employeeList.stream().map((emp) -> modelMapper.map(emp, EmployeeInfoPojo.class))
                    .collect(Collectors.toList());

但在测试时,模拟ModelMapper后,返回的列表中所有条目都被最后一个convertedPojo2覆盖,问题出在这段循环存根的代码:

for(EmployeeInfoPojo co : employeesResult){
    BDDMockito.when(modelMapper.map(any(),any()))
                    .thenReturn(co);
}

问题原因

Mockito的when(...).thenReturn(...)是覆盖式存根,每次调用都会替换之前的存根配置。循环结束后,modelMapper.map(any(),any())的返回值会被设置为最后一个循环的convertedPojo2,因此所有调用都会返回这个对象。

解决方案

方案1:按实体参数精准匹配返回值

针对每个EmployeeEntity实例,指定对应的EmployeeInfoPojo返回值,确保映射关系准确:

// 给第一个实体指定对应的DTO
BDDMockito.when(modelMapper.map(eq(employee), eq(EmployeeInfoPojo.class)))
          .thenReturn(convertedPojo1);
// 给第二个实体指定对应的DTO
BDDMockito.when(modelMapper.map(eq(employee2), eq(EmployeeInfoPojo.class)))
          .thenReturn(convertedPojo2);

这种方式依赖实体的equals方法(若用Lombok Builder生成,默认会实现该方法),能保证每个实体映射到正确的DTO。

方案2:按调用顺序链式返回

如果stream处理实体的顺序固定(和列表添加顺序一致),可以用链式thenReturn指定多次调用的返回值:

BDDMockito.when(modelMapper.map(any(), eq(EmployeeInfoPojo.class)))
          .thenReturn(convertedPojo1, convertedPojo2);

第一次调用modelMapper.map返回convertedPojo1,第二次返回convertedPojo2,刚好匹配stream处理两个实体的顺序。

方案3:自定义Answer逻辑动态返回

如果列表较长,不想写多个存根,可以用Answer接口自定义映射逻辑,根据传入的实体返回对应DTO:

BDDMockito.when(modelMapper.map(any(EmployeeEntity.class), eq(EmployeeInfoPojo.class)))
          .thenAnswer(invocation -> {
              EmployeeEntity inputEmp = invocation.getArgument(0);
              // 根据实体ID匹配对应的DTO
              if ("1L".equals(inputEmp.getId())) {
                  return convertedPojo1;
              } else if ("2L".equals(inputEmp.getId())) {
                  return convertedPojo2;
              }
              // 处理未匹配的情况,可返回null或抛异常
              throw new IllegalArgumentException("Unknown employee: " + inputEmp.getId());
          });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 19:05:38