【问题标题】:Spring Boot Test: Test Response throws "Could not find acceptable representation" , App works correctlySpring Boot 测试:测试响应抛出“找不到可接受的表示”,应用程序正常工作
【发布时间】:2017-01-01 21:51:01
【问题描述】:

我正在使用 Spring Boot 创建一个应用程序。当我运行我的应用程序并测试服务时,我得到了正确的结果。

但是,当我运行如下所示的测试时:

public class CatalogControllerTet {
    private MockMvc mvc;
    @Autowired
    private WebApplicationContext context;
    @Autowired
    private CatalogRepository catalogRepository;

    @Before
    public void setUp() throws Exception {
        this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
    }

    @Test
    public void getHello() throws Exception {

        MvcResult r = mvc.perform(MockMvcRequestBuilders
                .get("/catalogs")
                .accept(MediaType.APPLICATION_JSON)).andReturn();
        String content = r.getResponse().getContentAsString();
        int i = 100;
    }
}

当我在测试中设置断点时,我看到了这一点。我注意到的一件事是,我在“supportedMediaTypes”列表中没有看到任何提到 JSON 的内容。

我还看到了其他一些与我类似的问题,但它们被追溯到没有任何 getter/setter 或与 Jackson 库有关的响应对象。服务启动并正确运行的事实意味着不是这些问题。

非常感谢您对此的任何帮助。

【问题讨论】:

  • 您能分享有关端点实施的详细信息吗?另外,你不需要让你的测试类知道配置类/文件吗?
  • 真的没有端点配置,它就在那里.. "Ampersand"RunWith(SpringRunner.class) "Ampersand"SpringBootTest "Ampersand"EnableConfigurationProperties "Ampersand"ComponentScan("com.curator.application .domain,com.curator.application.repositories,com.curator.application.services") "Ampersand"EnableJpaRepositories(basePackages = {"com.curator.application.repositories"}) "Ampersand"DataJpaTest 在我的测试顶部文件。现在,我只是想让 POC 正确运行。

标签: java spring spring-mvc testing spring-boot


【解决方案1】:

我将@DataJpaTest 列为集成测试文件的注释。为什么会出现此错误,我永远不会知道,但确实如此。

作品:

@RunWith(SpringRunner.class)
@SpringBootTest
public class CatalogControllerITTest {
...

不起作用:

@RunWith(SpringRunner.class)
@SpringBootTest
@DataJpaTest
public class CatalogControllerITTest {
...

非常、非常令人惊讶和阴险的行为,因为永远不会怀疑注释会对 servlet 处理响应的方式产生任何影响。

【讨论】:

    【解决方案2】:

    您的控制器可能如下所示。

    package hello;
    
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @RestController
    public class HelloController {
    
        @RequestMapping(value="/catalogs", produces={"application/json"})
        @ResponseBody
        public String catalogs() {
            return "{\"catalogslist\":[], \"tupleslist\":[]}";
        }
    
    }
    

    那么下面的测试就成功了。

    package hello;
    
    import static org.hamcrest.Matchers.equalTo;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
    
    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.boot.test.SpringApplicationConfiguration;
    import org.springframework.http.MediaType;
    import org.springframework.mock.web.MockServletContext;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    import org.springframework.test.context.web.WebAppConfiguration;
    import org.springframework.test.web.servlet.MockMvc;
    import org.springframework.test.web.servlet.MvcResult;
    import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
    import org.springframework.test.web.servlet.setup.MockMvcBuilders;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringApplicationConfiguration(classes = MockServletContext.class)
    @WebAppConfiguration
    public class HelloControllerTest {
    
        private MockMvc mvc;
    
        @Before
        public void setUp() throws Exception {
            mvc = MockMvcBuilders.standaloneSetup(new HelloController()).build();
        }
    
        @Test
        public void getHello() throws Exception {
    
            MvcResult r = mvc.perform(MockMvcRequestBuilders
                    .get("/")
                    .accept(MediaType.APPLICATION_JSON)).andReturn();
    
    
            mvc.perform(MockMvcRequestBuilders.get("/catalogs").accept(MediaType.APPLICATION_JSON))
                    .andExpect(status().isOk())
                    .andExpect(content().string(equalTo("{\"catalogslist\":[], \"tupleslist\":[]}")));
        }
    }
    

    测试成功。

    如果您需要样板,欢迎使用我的boilerplate 进行新的 Spring Boot 项目。你只需克隆它并运行它:

    git clone https://github.com/montao/spring-boot-loaded.git
    Cloning into 'spring-boot-loaded'...
    remote: Counting objects: 25, done.
    remote: Total 25 (delta 0), reused 0 (delta 0), pack-reused 25
    Unpacking objects: 100% (25/25), done.
    Checking connectivity... done.
    dac@dac-Latitude-E7450 ~/spring-boot-loaded> ls
    spring-boot-loaded/
    dac@dac-Latitude-E7450 ~/spring-boot-loaded> cd spring-boot-loaded/
    dac@dac-Latitude-E7450 ~/s/spring-boot-loaded> gradle bootRun
    Starting a Gradle Daemon (subsequent builds will be faster)
    :compileJava
    :processResources UP-TO-DATE
    :classes
    :findMainClass
    :bootRun
    
      .   ____          _            __ _ _
     /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
    ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
     \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
      '  |____| .__|_| |_|_| |_\__, | / / / /
     =========|_|==============|___/=/_/_/_/
     :: Spring Boot ::        (v1.3.6.RELEASE)
    

    一个更高级的示例实际上是从 java 对象创建 json,然后对其进行测试。

    控制器

    package hello;
    
    import com.fasterxml.jackson.core.JsonGenerationException;
    import com.fasterxml.jackson.databind.JsonMappingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.ObjectWriter;
    import org.springframework.http.MediaType;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.w3c.dom.Entity;
    
    import java.io.File;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    import static org.springframework.web.bind.annotation.RequestMethod.GET;
    
    @RestController
    class HelloController {
        private class User {
    
            private String name;
    
            public int getAge() {
                return age;
            }
    
            void setAge(int age) {
                this.age = age;
            }
    
            private int age;
    
            public List<String> getMessages() {
                return messages;
            }
    
            void setMessages(List<String> messages) {
                this.messages = messages;
            }
    
            private List<String> messages;
    
            public String getName() {
                return name;
            }
    
            void setName(String name) {
                this.name = name;
            }
    
            //getters and setters
        }
    
        private User createDummyUser() {
    
            User user = new User();
    
            user.setName("Mallory");
            user.setAge(33);
    
            List<String> msg = new ArrayList<>();
            msg.add("hello jackson 1");
            msg.add("hello jackson 2");
            msg.add("hello jackson 3");
    
            user.setMessages(msg);
    
            return user;
    
        }
    
        @RequestMapping(value = "/catalogs2", produces = {"application/json"})
        @ResponseBody
        public String catalogs() {
            String jsonInString = "";
            String json = "";
            User user = createDummyUser();
            ObjectMapper mapper = new ObjectMapper();
            try {
                //Convert object to JSON string and save into file directly
                mapper.writeValue(new File("user.json"), user);
    
                //Convert object to JSON string
                jsonInString = mapper.writeValueAsString(user);
                System.out.println(jsonInString);
    
                //Convert object to JSON string and pretty print
                jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(user);
                ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
                json = ow.writeValueAsString(jsonInString);
    
            } catch (JsonGenerationException e) {
                e.printStackTrace();
            } catch (JsonMappingException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return json;
        }
    
    }
    

    测试

    package hello;
    
    import static org.hamcrest.Matchers.equalTo;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
    
    import com.fasterxml.jackson.core.JsonGenerationException;
    import com.fasterxml.jackson.databind.JsonMappingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.ObjectWriter;
    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.boot.test.SpringApplicationConfiguration;
    import org.springframework.http.MediaType;
    import org.springframework.mock.web.MockServletContext;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    import org.springframework.test.context.web.WebAppConfiguration;
    import org.springframework.test.web.servlet.MockMvc;
    import org.springframework.test.web.servlet.MvcResult;
    import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
    import org.springframework.test.web.servlet.setup.MockMvcBuilders;
    
    import java.io.File;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringApplicationConfiguration(classes = MockServletContext.class)
    @WebAppConfiguration
    public class HelloControllerTest {
        private class User {
    
            private String name;
    
            public int getAge() {
                return age;
            }
    
            void setAge(int age) {
                this.age = age;
            }
    
            private int age;
    
            public List<String> getMessages() {
                return messages;
            }
    
            void setMessages(List<String> messages) {
                this.messages = messages;
            }
    
            private List<String> messages;
    
            public String getName() {
                return name;
            }
    
            void setName(String name) {
                this.name = name;
            }
    
            //getters and setters
        }
    
        private User createDummyUser() {
    
            User user = new User();
    
            user.setName("Mallory");
            user.setAge(33);
    
            List<String> msg = new ArrayList<>();
            msg.add("hello jackson 1");
            msg.add("hello jackson 2");
            msg.add("hello jackson 3");
    
            user.setMessages(msg);
    
            return user;
    
        }
    
        private MockMvc mvc;
    
        @Before
        public void setUp() throws Exception {
            mvc = MockMvcBuilders.standaloneSetup(new HelloController()).build();
        }
    
        @Test
        public void getHello() throws Exception {
    
            MvcResult r = mvc.perform(MockMvcRequestBuilders
                    .get("/")
                    .accept(MediaType.APPLICATION_JSON)).andReturn();
    
    
            String jsonInString = "";
            String json = "";
            User user = createDummyUser();
            ObjectMapper mapper = new ObjectMapper();
            try {
                //Convert object to JSON string and save into file directly
                mapper.writeValue(new File("user.json"), user);
    
                //Convert object to JSON string
                jsonInString = mapper.writeValueAsString(user);
                System.out.println(jsonInString);
    
                //Convert object to JSON string and pretty print
                jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(user);
                ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
                json = ow.writeValueAsString(jsonInString);
    
                mvc.perform(MockMvcRequestBuilders.get("/catalogs2").accept(MediaType.APPLICATION_JSON))
                        .andExpect(status().isOk())
    
    
                        .andExpect(content().string(equalTo(json)));
    
            } catch (JsonGenerationException e) {
                e.printStackTrace();
            } catch (JsonMappingException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    测试

    【讨论】:

    • 所以我不能返回一个对象并以透明的方式将其序列化为 JSON?部署服务时序列化似乎工作正常,但在测试期间失败..
    • @FlexFiend 我添加了一个更高级的示例,您可以从 Java 对象创建 json 并将其序列化 + 测试。希望对你有用。
    猜你喜欢
    • 2019-01-23
    • 1970-01-01
    • 2017-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-21
    • 2023-03-20
    • 1970-01-01
    相关资源
    最近更新 更多