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

如何从嵌套集合中提取内部元素构造Stream流用于JUnit参数化测试

JUnit参数化测试ArgumentsProvider流处理实现方案

原有代码核心问题

  • 循环中复用同一个instanceData数组,最终List存储的所有引用指向同一个数组,所有值都会被最后一次循环的结果覆盖
  • flatMap使用逻辑错误:硬编码返回字符串"x[0]"而非读取数组的实际元素,且当前场景无需使用flatMap
  • 返回值结构不匹配:将整个Stream对象包装进单个Arguments实例,JUnit无法解析为测试方法要求的3个入参

基于现有逻辑的修复代码

class KdTreeTest {
    static class KdTreeArgumentsProvider implements ArgumentsProvider {
        final static File folder = new File("src/main/resources/kdtests/");
        RectHV r = new RectHV(0.1, 0.1, 0.5, 0.6);
        Point2D p1 = new Point2D(0.1, 0.2);
        Point2D p2 = new Point2D(0.8, 0.9);
        Point2D[] expectedPoints = {p1, p2};

        @Override
        public Stream<? extends Arguments> provideArguments(ExtensionContext extensionContext) throws Exception {
            List<Object[]> l = new ArrayList<>();
            for (final File fileEntry : folder.listFiles()) {
                String fileName = fileEntry.getName().toUpperCase();
                if (fileName.endsWith(".TXT")) {
                    Scanner scanner = new Scanner(fileEntry);
                    KdTree kt = new KdTree();
                    while (scanner.hasNext()) {
                        double x = scanner.nextDouble();
                        double y = scanner.nextDouble();
                        kt.insert(new Point2D(x, y));
                    }
                    // 每次循环新建数组,避免引用复用
                    Object[] instanceData = new Object[]{kt, r, expectedPoints};
                    l.add(instanceData);
                }
            }
            // 直接将每个数组转为Arguments实例,组成Stream返回
            return l.stream().map(Arguments::of);
        }
    }

    @DisplayName("should create a rectangle with the given coordinates and test KdTree's range() function")
    @ParameterizedTest(name = "{index}=> kt={0},r={1},expectedPoints={2}")
    @ArgumentsSource(KdTreeArgumentsProvider.class)
    void range(KdTree kt, RectHV r, Point2D[] expectedPoints) {
        Assertions.assertNotNull(kt.range(r));
    }
}

纯Stream实现(无需提前创建ArrayList)

不需要提前把所有参数存入集合,直接流式处理文件即可满足需求:

@Override
public Stream<? extends Arguments> provideArguments(ExtensionContext extensionContext) throws Exception {
    RectHV r = new RectHV(0.1, 0.1, 0.5, 0.6);
    Point2D[] expectedPoints = {new Point2D(0.1, 0.2), new Point2D(0.8, 0.9)};

    return Arrays.stream(folder.listFiles())
            .filter(file -> file.getName().toUpperCase().endsWith(".TXT"))
            .map(file -> {
                try {
                    KdTree kt = new KdTree();
                    Scanner scanner = new Scanner(file);
                    while (scanner.hasNext()) {
                        kt.insert(new Point2D(scanner.nextDouble(), scanner.nextDouble()));
                    }
                    return Arguments.of(kt, r, expectedPoints);
                } catch (FileNotFoundException e) {
                    throw new RuntimeException(e);
                }
            });
}

补充说明

flatMap适用于扁平化嵌套集合的场景,比如Stream<List<T>>转Stream<T>,你的场景只需要将每组参数一对一转为Arguments实例,使用map即可满足需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 05:57:03