使用REST Assured与Java Hamcrest检查含不同类型值的数组元素
问题:验证JSON数组中对象的键值对时遇到类型不匹配与方法解析错误
我需要验证某API返回的JSON数组中是否存在包含指定键值对的对象,但遇到两个问题:一是值的类型不匹配时验证失效,二是IDE报错无法解析allOf方法。
我编写的代码如下:
"$", hasItem( allOf( hasEntry("id", "someid123"), hasEntry("age", 99) ) );
IDE报错信息:
Cannot resolve method 'allOf(Matcher<Map<? extends K, ? extends V>>, Matcher<Map<? extends K, ? extends V>>)'
当把99改为字符串类型时代码能正常运行,但我无法控制API返回的数值类型(API返回的age是数值类型)。附API返回的响应示例:
[ { "id": "someid123", "age": 99 }, { "id": "anotherid789", "age": 77 } ]
推测这些JSON对象在内部会被转换为Java Map。
解决方法
1. 修复allOf方法的类型推断问题
allOf需要接收同类型的Matcher参数,由于泛型类型推断模糊导致报错,需明确导入正确的静态方法并确保参数类型一致。修改后的代码需指定Matcher针对Map<String, Object>类型:
"$", hasItem( CoreMatchers.allOf( Matchers.hasEntry("id", "someid123"), Matchers.hasEntry("age", 99) ) )
同时要确保导入以下静态方法:
import static org.hamcrest.CoreMatchers.allOf; import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.hasItem;
2. 处理数值类型不匹配问题
API返回的数值可能是Integer、Long等类型,直接用字面量99(默认int)可能因类型不匹配导致验证失败,可通过以下两种方式解决:
方式一:用equalToObject忽略类型差异匹配等值
equalToObject会基于实际值而非类型进行比较,适用于不确定返回数值类型的场景:
Matchers.hasEntry("age", CoreMatchers.equalToObject(99))
方式二:明确匹配对应数值类型
如果确定API返回的是Integer类型,直接用99;如果是Long类型,用99L:
// 匹配Integer类型的99 Matchers.hasEntry("age", 99); // 匹配Long类型的99 Matchers.hasEntry("age", 99L);
3. 完整可运行示例
import static org.hamcrest.CoreMatchers.allOf; import static org.hamcrest.CoreMatchers.equalToObject; import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.hasItem; import static org.junit.Assert.assertThat; import java.util.List; import java.util.Map; public class ApiResponseTest { public void testResponseContainsTargetObject() { // 模拟API返回转换后的List<Map<String, Object>> List<Map<String, Object>> response = List.of( Map.of("id", "someid123", "age", 99), Map.of("id", "anotherid789", "age", 77) ); assertThat(response, hasItem( allOf( hasEntry("id", "someid123"), hasEntry("age", equalToObject(99)) ) )); } }
内容的提问来源于stack exchange,提问作者programmer122
相关产品推荐
相关产品推荐

