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

如何用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 04:17:09