编写Arquillian测试Java Map Tuple方法时遇空值问题求助
Arquillian测试中Map元素获取返回null的排查与修复
问题背景
实现了regionMap方法,通过JPA查询CanadianPersonalIncomeTaxRate实体,将结果转换为以省份名称(provinceName)为键、省份缩写(provinceAbbreviation)为值的Map<String, String>,返回加拿大唯一省份的映射。编写Arquillian测试时,Map的大小验证通过,但通过get(0)、get(1)获取元素时返回null,无法得到预期的省份信息。
regionMap方法代码
// provinceName is key, provinceAbbreviation is value public Map<String, String> regionMap() { return em.createQuery(""" select distinct p.provinceName as prov_id, p.provinceAbbreviation as prov_value from CanadianPersonalIncomeTaxRate p order by p.provinceName """, Tuple.class) .getResultStream() .collect(Collectors.toMap( tuple -> tuple.get(0, String.class), tuple -> tuple.get(1, String.class) ) ); }
原测试代码
@Order(2) @ParameterizedTest @CsvSource({ "13,Alberta,AB,Yukon,YT" }) void regionMap(int expectedSize, String firstProvinceName, String firstProvinceAbbreviation, String lastProvinceName, String lastProvinceAbbreviation) { assertNotNull(_canadianPersonalIncomeTaxRateRepository); // Arrange Map<String, String> provinceList = _canadianPersonalIncomeTaxRateRepository.regionMap(); // Assert assertEquals(expectedSize, provinceList.size()); assertEquals(firstProvinceName, provinceList.get(0) ); assertEquals(firstProvinceAbbreviation, provinceList.get(1) ); // assertEquals(lastProvinceName, provinceList.get() ); // assertEquals(lastProvinceAbbreviation, provinceList.get() ); }
错误原因
核心问题是混淆了Map与List的访问逻辑:
regionMap返回的Map<String, String>是以省份名称(如"Alberta")作为键的键值对集合,不是按索引顺序存储的List。- 测试中使用
provinceList.get(0)、provinceList.get(1),是尝试用Integer类型的数字索引作为键去查找Map中的元素,但Map的键是String类型的省份名称,完全不匹配,因此返回null。
修复后的测试代码
将Map元素的获取方式改为以省份名称为键,对应断言省份缩写是否符合预期:
@Order(2) @ParameterizedTest @CsvSource({ "13,Alberta,AB,Yukon,YT" }) void regionMap(int expectedSize, String firstProvinceName, String firstProvinceAbbreviation, String lastProvinceName, String lastProvinceAbbreviation) { assertNotNull(_canadianPersonalIncomeTaxRateRepository); // Arrange // 变量名修正为更准确的provinceMap,避免误解为List Map<String, String> provinceMap = _canadianPersonalIncomeTaxRateRepository.regionMap(); // Assert assertEquals(expectedSize, provinceMap.size()); // 用省份名称作为键,获取对应的缩写并断言 assertEquals(firstProvinceAbbreviation, provinceMap.get(firstProvinceName)); // 验证最后一个省份的映射 assertEquals(lastProvinceAbbreviation, provinceMap.get(lastProvinceName)); }
额外优化建议
- Tuple取值更安全:在
regionMap方法中,建议使用查询语句中定义的别名(prov_id、prov_value)来获取Tuple值,避免因查询字段顺序调整导致的错误:
.collect(Collectors.toMap( tuple -> tuple.get("prov_id", String.class), tuple -> tuple.get("prov_value", String.class) )
- 变量名规范:原测试中的
provinceList变量名不符合实际类型,改为provinceMap更清晰,减少后续维护误解。
内容的提问来源于stack exchange,提问作者CheckDeck
相关产品推荐
相关产品推荐

