如何通过@ParameterizedTest传递JSON键值对作为测试参数?
问题
我正在进行FizzBuzz功能测试,已在pom.xml中引入JSON相关依赖,测试可正常通过。当前使用@ParameterizedTest配合@JsonFileSource加载/small-test-data.json文件,测试方法接收整个JsonObject作为参数,遍历其键值对进行断言。但我希望将JSON中的key(输入数值)和value(预期结果)作为独立参数传入@ParameterizedTest,而非整个JsonObject,请问该如何实现?
现有JSON测试数据
{ "1": "1", "2": "2", "3": "Fizz", "4": "4", "5": "Buzz", "6": "Fizz", "7": "7", "8": "8", "9": "Fizz", "10": "Buzz", "11": "11", "12": "Fizz", "13": "13", "14": "14", "15": "FizzBuzz" }
现有测试代码
@DisplayName("TESTING WITH SMALL JSON FILE") @ParameterizedTest() @JsonFileSource(resources = "/small-test-data.json") @Order(-1) void testSmallDataJsonFile(JsonObject jsonObject) { jsonObject.forEach((k,v)-> { assertEquals(jsonObject.getString(k),FizzBuzz.compute(Integer.parseInt(k))); log.info("✔ actual={},expected={}",v,FizzBuzz.compute(Integer.parseInt(k))); }); }
解决方案
方法一:调整JSON为数组结构(最便捷)
@JsonFileSource原生支持解析JSON数组为多组测试参数,只需修改JSON文件结构为包含输入和预期值的数组对象:
修改后的small-test-data.json:
[ {"input": 1, "expected": "1"}, {"input": 2, "expected": "2"}, {"input": 3, "expected": "Fizz"}, {"input": 4, "expected": "4"}, {"input": 5, "expected": "Buzz"}, {"input": 6, "expected": "Fizz"}, {"input": 7, "expected": "7"}, {"input": 8, "expected": "8"}, {"input": 9, "expected": "Fizz"}, {"input": 10, "expected": "Buzz"}, {"input": 11, "expected": "11"}, {"input": 12, "expected": "Fizz"}, {"input": 13, "expected": "13"}, {"input": 14, "expected": "14"}, {"input": 15, "expected": "FizzBuzz"} ]
对应的测试代码:
@DisplayName("TESTING WITH SMALL JSON FILE (数组格式)") @ParameterizedTest @JsonFileSource(resources = "/small-test-data.json") @Order(-1) void testSmallDataJsonFile(int input, String expected) { String actual = FizzBuzz.compute(input); assertEquals(expected, actual); log.info("✔ actual={}, expected={}", actual, expected); }
方法二:自定义ArgumentsProvider(保留原JSON结构)
如果不想修改现有JSON文件,可自定义ArgumentsProvider来解析原JSON的键值对,将其转换为独立的测试参数:
- 实现自定义ArgumentsProvider:
public class FizzBuzzJsonArgumentsProvider implements ArgumentsProvider { @Override public Stream<? extends Arguments> provideArguments(ExtensionContext context) throws IOException { InputStream inputStream = getClass().getResourceAsStream("/small-test-data.json"); JsonObject jsonObject = Json.createReader(inputStream).readObject(); return jsonObject.entrySet().stream() .map(entry -> Arguments.of(Integer.parseInt(entry.getKey()), entry.getValue().toString())); } }
- 修改测试代码使用自定义提供者:
@DisplayName("TESTING WITH SMALL JSON FILE (原结构)") @ParameterizedTest @ArgumentsSource(FizzBuzzJsonArgumentsProvider.class) @Order(-1) void testSmallDataJsonFile(int input, String expected) { String actual = FizzBuzz.compute(input); assertEquals(expected, actual); log.info("✔ actual={}, expected={}", actual, expected); }
两种方法都能让每个键值对作为独立测试用例执行,而非一次性遍历所有数据。
内容的提问来源于stack exchange,提问作者Moon_Sigma
相关产品推荐
相关产品推荐

