如何将Map键值对作为独立参数传入JUnit参数化测试
问题:将静态Map的键值对作为JUnit参数化测试的独立参数
我是Java新手,对堆栈追踪(stacktrace)也不熟悉,请多包涵。我有一个静态Map,希望将其中的键值对作为独立参数传入JUnit测试中。
我的Map定义如下:
Map<String, String> myMap = Map.ofEntries( entry("foo1", "bar1"), entry("foo2", "bar2"));
我设想的测试方法如下:
@ParameterizedTest @MethodSource("provideNamespaceGroupIdMapping") void my_test(String key, String value) { prepareFile(key); prepareOtherStuff(value); // ...其他测试逻辑 }
并编写了一个提供参数的方法:
private static Stream<Arguments> provideNamespaceGroupIdMapping() { return Stream.of( Arguments.of( myMap.keySet().stream().toString(), myMap.values().stream().toString())); }
但运行后出现了IndexOutOfBoundsException异常:
java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1
我尝试了其他方法但都没有成功,请问是否有实现该需求的解决方案?
解决方案
错误原因分析
你当前的写法存在两个核心问题:
- 错误地将
keySet().stream().toString()和values().stream().toString()作为参数传入,这两个调用返回的是流对象的字符串表示(比如java.util.stream.ReferencePipeline$3@xxxxxx),并非实际的键值内容。 - 只生成了一组参数,但JUnit参数化测试需要为Map中的每一对键值对单独生成一组参数,这样测试方法才会被多次执行,每次处理一对键值。
正确实现方式
修改参数提供方法,遍历Map的entrySet,为每个键值对生成独立的Arguments实例:
private static Stream<Arguments> provideNamespaceGroupIdMapping() { return myMap.entrySet() .stream() .map(entry -> Arguments.of(entry.getKey(), entry.getValue())); }
说明
- 这段代码会遍历
myMap中的所有键值对,每个entry都会转化为一个包含key和value的Arguments对象。 - JUnit会为每一组参数单独执行一次
my_test方法,也就是会执行两次测试:第一次传入"foo1"和"bar1",第二次传入"foo2"和"bar2"。 - 注意:
myMap必须是静态变量,因为provideNamespaceGroupIdMapping是静态方法,无法直接访问非静态成员。如果你的myMap不是静态的,需要将其修改为静态,或者在参数方法内部初始化Map。
内容的提问来源于stack exchange,提问作者Shazzer
相关产品推荐
相关产品推荐

