如何用Mockito编写方法创建多类型Mock对象列表?
批量生成不同类型Mock对象列表的解决方案
我完全懂你的困扰——单个Mock对象随手就能用Mockito创建,但要批量生成不同实现类的Mock还得混合到一起,确实得花点心思。下面我给你一套通用的解决方案,不管后续新增多少个SubEntity的实现类,都能轻松扩展使用。
首先咱们先明确基础类结构(方便你对应自己的代码):
// 你的SubEntity接口 interface SubEntity { // 假设接口有一些方法,比如getId() String getId(); } // 实现类A class SubEntityA implements SubEntity {} // 实现类B class SubEntityB implements SubEntity {} // 包含subEntities属性的Entity类 class Entity { private List<SubEntity> subEntities; public List<SubEntity> getSubEntities() { return subEntities; } public void setSubEntities(List<SubEntity> subEntities) { this.subEntities = subEntities; } }
第一步:写一个通用的Mock批量生成工具类
这个工具方法接收一个Map,key是SubEntity的实现类,value是你要生成的该类型Mock的数量,最后返回混合好的Mock列表:
import org.mockito.Mockito; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.function.Consumer; public class MockGenerator { // 基础版:仅批量生成Mock,不配置行为 public static <T> List<T> generateMixedMocks(Map<Class<? extends T>, Integer> typeCountMap) { List<T> mockList = new ArrayList<>(); for (Map.Entry<Class<? extends T>, Integer> entry : typeCountMap.entrySet()) { Class<? extends T> entityType = entry.getKey(); int count = entry.getValue(); for (int i = 0; i < count; i++) { // 用Mockito创建对应类型的Mock对象 T mockInstance = Mockito.mock(entityType); mockList.add(mockInstance); } } return mockList; } // 进阶版:支持统一配置所有Mock的行为(比如设置方法返回值) public static <T> List<T> generateMixedMocks(Map<Class<? extends T>, Integer> typeCountMap, Consumer<T> mockConfigurator) { List<T> mockList = new ArrayList<>(); for (Map.Entry<Class<? extends T>, Integer> entry : typeCountMap.entrySet()) { Class<? extends T> entityType = entry.getKey(); int count = entry.getValue(); for (int i = 0; i < count; i++) { T mockInstance = Mockito.mock(entityType); // 给每个Mock配置自定义行为 mockConfigurator.accept(mockInstance); mockList.add(mockInstance); } } return mockList; } }
第二步:在测试用例中使用工具类
比如你需要生成3个SubEntityA、2个SubEntityB,然后把它们塞到Entity的subEntities里:
import org.junit.jupiter.api.Test; import java.util.HashMap; import java.util.Map; import java.util.UUID; import static org.junit.jupiter.api.Assertions.assertEquals; public class EntityTest { @Test void testEntityWithMixedSubEntities() { // 1. 定义每种SubEntity实现类需要生成的数量 Map<Class<? extends SubEntity>, Integer> mockCounts = new HashMap<>(); mockCounts.put(SubEntityA.class, 3); mockCounts.put(SubEntityB.class, 2); // 后续新增SubEntityC的话,直接加一行:mockCounts.put(SubEntityC.class, 5); 就行 // 2. 生成混合Mock列表(这里用进阶版,给所有Mock设置getId()的返回值) List<SubEntity> mixedSubEntities = MockGenerator.generateMixedMocks(mockCounts, mock -> { // 给每个SubEntity Mock设置随机ID Mockito.when(mock.getId()).thenReturn(UUID.randomUUID().toString()); }); // 3. 把列表设置到Entity对象中 Entity testEntity = new Entity(); testEntity.setSubEntities(mixedSubEntities); // 4. 验证结果是否符合预期 assertEquals(5, testEntity.getSubEntities().size()); // 3+2=5 long subEntityACount = testEntity.getSubEntities().stream() .filter(e -> e instanceof SubEntityA) .count(); assertEquals(3, subEntityACount); long subEntityBCount = testEntity.getSubEntities().stream() .filter(e -> e instanceof SubEntityB) .count(); assertEquals(2, subEntityBCount); } }
额外优化:打乱列表顺序(可选)
如果需要让不同类型的Mock随机排列,更贴近真实场景,只需要在工具方法返回列表前加一行:
import java.util.Collections; // 在generateMixedMocks方法最后return之前加上 Collections.shuffle(mockList);
内容的提问来源于stack exchange,提问作者Aleksei Golubev
相关产品推荐
相关产品推荐

