【问题标题】:Java MockMvc Test and Match Json StringJava MockMvc 测试和匹配 Json 字符串
【发布时间】:2021-12-22 13:33:09
【问题描述】:

我想匹配get-request的输出,并匹配手动提供的json字符串,基本上是从整个输出中复制一个json字符串并测试。尝试了很多方法但它没有发生,我无法从数据库中删除所有行以匹配一个字符串,所以,我只想匹配一个 json 字符串 - 如下所示

{
        "instanceName": "",
        "read": 1,
        "swProduct": "Area 1",
        "swProductModule": "Regular 1"
    },

这是我的测试代码---


@SpringBootTest(classes = TestApplication.class)
@ActiveProfiles("dev")
@AutoConfigureMockMvc

public class SwStatusCheckTest {

    @Autowired
    private MockMvc mvc;

    @IfProfileValue(name = "spring.profiles.active", values = { "dev" })
    @Test
    @DisplayName("GET Method /SwCheckStatus check success")
    public void testStatusSuccess() throws Exception {

        MvcResult result =  mvc.perform(get("/status/SwCheckStatus"))
                .andDo(print())
                .andExpect(status().isOk())
                .andReturn();
                //.andExpect(content().json("{\"services\":[\"OutboundMessageService\"]}", true));

        String actualJson = result.getResponse().getContentAsString();
        String expectedJson = "[{\"instanceName\":\"Instance C\", \"read\" : 1, \"swProduct\" : \"Area 3\", \"swProductModule\" : \"Spring Boot 3\"}]";


        assertThat(expectedJson).isIn(actualJson);

}
}

整个 Postman json 结果的输出如下所示 ---

[
    {
        "instanceName": "",
        "read": 1,
        "swProduct": "Area 1",
        "swProductModule": "Regular 1"
    },
    {
        "instanceName": "",
        "read": 1,
        "swProduct": "Area 1",
        "swProductModule": "Regular 2"
    },
    {
        "instanceName": "",
        "read": 1,
        "swProduct": "Area 1",
        "swProductModule": "Spring Boot 1"
    },
    {
        "instanceName": "",
        "read": 1,
        "swProduct": "Area 1",
        "swProductModule": "Spring Boot 2"
    },

Intellij 说 -- 它的期望和字符串匹配......但测试失败 -- 检查附件 --- [在此处输入图片说明][1]

非常感谢您对执行测试的任何见解帮助。 [1]:https://i.stack.imgur.com/FE2dT.jpg

【问题讨论】:

    标签: java spring-boot junit mockmvc


    【解决方案1】:

    isIn 不是比较字符串,而是数组。

    您可以将JSONMap 进行比较,与jackson-databind 和Google Guava

    
    import static org.assertj.core.api.Assertions.assertThat;
    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
    import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
    
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.google.common.collect.Maps;
    import java.util.List;
    import java.util.Map;
    import org.junit.jupiter.api.DisplayName;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.annotation.IfProfileValue;
    import org.springframework.test.context.ActiveProfiles;
    import org.springframework.test.web.servlet.MockMvc;
    import org.springframework.test.web.servlet.MvcResult;
    
    @SpringBootTest(classes = TestApplication.class)
    @ActiveProfiles("dev")
    @AutoConfigureMockMvc
    
    public class SwStatusCheckTest {
    
        @Autowired
        private MockMvc mvc;
    
        @IfProfileValue(name = "spring.profiles.active", values = { "dev" })
        @Test
        @DisplayName("GET Method /SwCheckStatus check success")
        public void testStatusSuccess() throws Exception {
    
            MvcResult result = mvc.perform(get("/status/SwCheckStatus"))
                .andDo(print())
                .andExpect(status().isOk())
                .andReturn();
            //.andExpect(content().json("{\"services\":[\"OutboundMessageService\"]}", true));
    
            ObjectMapper mapper = new ObjectMapper();
    
            List<? extends Map<String, Object>> actualJson = mapper.readValue(result.getResponse().getContentAsString(),
                List.class);
    
            Map<String, Object> expected = Map.of("instanceName", "", "read", 1, "swProduct", "Area 1", "swProductModule",
                "Regular 1");
    
            boolean contains = false;
            for (Map<String, Object> a : actualJson) {
                boolean res = Maps.difference(a, expected).areEqual();
                if (res) {
                    contains = true;
                    break;
                }
            }
            assertThat(contains).isTrue();
        }
    }
    

    【讨论】:

      【解决方案2】:

      如果我正确阅读了您的问题以及您发布的图片,则问题可能是预期/实际字符串或测试中定义的条件(断言)。 “实际”字符串值是一个包含多个元素的数组,“预期”是一个只有一个元素的数组。由于只有一个元素的数组不包含在多个元素的数组中,所以它不起作用。

      如果代码发生更改,使得您要查找的“预期”值被写为 JUST 对象(不包括其封闭数组)

      { ... your object here ... }
      

      那么预期的“isIn”实际断言应该可以工作。

      【讨论】:

      • 我只需要匹配一个字符串...来自 result.getResponse().getContentAsString(); 的输出
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-14
      • 1970-01-01
      • 2018-01-01
      • 2017-08-03
      • 1970-01-01
      • 2019-09-10
      • 2011-05-22
      相关资源
      最近更新 更多