java - 检查 JSON 响应中的每个对象是否包含特定字段中的短语
问题描述
今天我需要为公共 API 消费者创建一个集成测试,并检查我找到的记录是否与查询参数匹配。
例如,我正在发送一个 GET 请求,例如
localhost:8080/nutritionix/productDetails?query=grilled
我想找出每个产品包含“烤”或“烤”或其他形式的相同短语,例如:food_name 字段中的“GRillEd”短语。
来自公共 API 的示例响应:
[
{
"food_name": "chicken grilled",
"serving_qty": 1,
"serving_unit": "piece",
"photo": {
"thumb": "https://d2xdmhkmkbyw75.cloudfront.net/1714_thumb.jpg"
}
},
{
"food_name": "grilled chicken thigh",
"serving_qty": 1,
"serving_unit": "thigh with skin",
"photo": {
"thumb": "https://d2xdmhkmkbyw75.cloudfront.net/8724_thumb.jpg"
}
},
{
"food_name": "grilled chicken wrap",
"serving_qty": 1,
"serving_unit": "wrap",
"photo": {
"thumb": "https://d2xdmhkmkbyw75.cloudfront.net/2562_thumb.jpg"
}
},
{
"food_name": "grilled cheese",
"serving_qty": 1,
"serving_unit": "sandwich",
"photo": {
"thumb": "https://d2xdmhkmkbyw75.cloudfront.net/1763_thumb.jpg"
}
},
{
"food_name": "Grilled Tilapia, Signature Grilled",
"serving_qty": 1,
"serving_unit": "fillet",
"brand_name": "Gorton's",
"nix_brand_id": "51db37b2176fe9790a8985bc",
"photo": {
"thumb": "https://d1r9wva3zcpswd.cloudfront.net/55178d395108f25f51667c2d.jpeg"
}
},
{
"food_name": "Grilled Gourmet Soft Taco, Grilled Chicken",
"serving_qty": 189,
"serving_unit": "g",
"brand_name": "Amigos Kings Classic",
"nix_brand_id": "521b95434a56d006cae297dc",
"photo": {
"thumb": "https://d2eawub7utcl6.cloudfront.net/images/nix-apple-grey.png"
}
}
]
下面的测试类:
@ExtendWith(SpringExtension.class)
@AutoConfigureMockMvc
@SpringBootTest
class NutritionixApiControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
void nutritionixSearchInstantTest() throws Exception {
ResultActions resultActions = mockMvc
.perform(MockMvcRequestBuilders.get("/nutritionix/productDetails?query=grilled")
.contentType(MediaType.APPLICATION_JSON)).andDo(print())
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$", hasSize(40)))
.andExpect(MockMvcResultMatchers.jsonPath("$[*].food_name", hasItems("grilled")))
.andExpect(MockMvcResultMatchers.jsonPath("$[0].food_name", containsString("grilled")));
}
不幸的是,这条线:
.andExpect(MockMvcResultMatchers.jsonPath("$[*].food_name", hasItems("grilled")))
导致断言错误,如:
java.lang.AssertionError: JSON path "$[*].food_name"
Expected: (a collection containing "grilled")
but: a collection containing "grilled" was "grilled chicken thigh", was "Fiesta Grilled Chicken", was "grilled zucchini", was "grilled octopus", was "grilled veggies", was "Grilled Chicken Pesto with Vegetables", was "Grilled Chicken Salad", was "grilled cheese", was "Grilled Chicken Strips", was "Grilled Chicken for Grilled Chicken Salad", was "grilled chicken", was "chicken grilled", was "Grilled Chicken Marinara, with Parmesan", was "Greek Dressing for Grilled Topped Salads", was "chilis grilled chicken salad", was "Caesar Dressing for Grilled Topped Salads", was "grilled onions", was "Grilled & Ready Grilled Chicken Breast Chunks", was "Grilled Cali Bowl, Grilled", was "Mesquite Grilled Chicken Fillets", was "grilled chicken salad", was "Grilled Chicken Marsala", was "Grilled Gourmet Soft Taco, Grilled Chicken", was "Grilled Chicken & Broccoli Alfredo", was "grilled salmon", was "Fire-Grilled Grilled Steak Salad", was "Grilled Tilapia, Signature Grilled", was "Grilled Salmon, Classic Grilled", was "Grilled Basil Chicken", was "grilled steak", was "grilled chicken wrap", was "grilled chicken sandwich", was "Big Sky Grilled Salad (grilled chicken)", was "grilled fish", was "Grilled Roll-Up, Grilled Chicken", was "grilled shrimp", was "grilled hamburger", was "grilled chicken breast", was "grilled vegetables", was "grilled asparagus"
我想要实现的是检查我在 JSON 响应中收到的所有对象是否在 food_name 字段中包含一个短语,我们在查询期间将其作为查询参数传递,包括小写和大写字母以及有趣的文本案例。
我想问题的出现是因为返回的记录模式缺乏标准化,例如:有时我们得到带有 food_name 字段的对象,它们是大写的,有时是小写的。
感谢您对如何改进我的 JSONPath 语法的任何帮助。
解决方案
问题是您正在检查结果的任何元素是否等于grilled
. 我认为您需要检查的是结果的每个元素是否都包含烤忽略大小写。
使用Hamcrest库(我认为您已经在使用它),您可以通过以下方式进行操作:
@Test
public void everyContainsStringIgnoringCase() {
List<String> foodNames = JsonPath.read(RESPONSE, "$[*].food_name");
assertThat(foodNames, Every.everyItem(containsStringIgnoringCase("grilled")));
}
响应是你的json。
推荐阅读
- java - `@Nullable @org.jetbrains.annotations.Nullable Intent data` 有什么作用,是否有必要?
- flutter - Flutter graphql 使用带配置单元的缓存,当使用警察“cacheAndNetwork”调用查询时,它总是使用没有缓存的网络
- javascript - 在 R 中,如何在 Sankey Graph 的链接/路径上显示值?
- datagridview - 带有自定义单元格编辑器的 DataGridView 在第一次尝试时不会推送用户值
- c++ - ( | vs. || ) C++ 中的“或”运算符比较
- python - Tensorflow.python.framework.errors_impl.InvalidArgumentError:除 3 以外的所有维度都必须匹配
- css - 如何为给定布局填充的 nextjs 图像赋予高度和宽度?
- javascript - Codepen 项目将不会部署。SCSS 不加载
- python - 使用 pymongo 启动 mongo / 获取 mongo 主机
- parsing - 如何使用 .. 和 -