如何从嵌套集合中提取内部元素构造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
相关产品推荐
相关产品推荐

