java - 检查 JSON 响应中的每个对象是否包含特定字段中的短语

标签 java json junit jsonpath hamcrest

今天我需要为公共(public) API 使用者创建一个集成测试,并检查我找到的记录是否与查询参数匹配。
例如,我发送一个 GET 请求,例如

localhost:8080/nutritionix/productDetails?query=grilled 

我想找出包含“grilled”或“Grilled”或其他形式的相同短语的每个产品,例如:food_name 字段中的“GRillEd”短语。

公共(public) 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")));
}

其中RESPONSE是你的json。

关于java - 检查 JSON 响应中的每个对象是否包含特定字段中的短语,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57658764/

相关文章:

javascript - 如何使用 React 中的 JSON 文件中的每个值生成组件?

java - 如何从字符串中提取 float 值数据

json - 如何解码 JSON 字符串中的 Base 64 字符串以生成 UIImage?

java - 如何实现简单的edittext语法高亮方法?

java - 在 Java 中将节点 append 到 xml

java - 无法从 JUnit 中的 Spring Boot 读取应用程序属性?

java - Hibernate 未在内存数据库中使用 H2 创建表

java - 使用 main 方法在 Java 中编写单元测试

java - 如何处理复杂数据结构的嵌套for循环?

Java 在线程中通过套接字发送对象