简体   繁体   中英

Spring Controller ModelAndView test MockMvc empty Response

I have this simple example setup to unit test spring Controller ModelAndView with MockMvc, but the response is always empty, even though in debug I can see that the controller code is executed.

Here's the code:

/src/main/java/controller/MvcController.java

package controller;

import java.util.HashMap;
import java.util.Map;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class MvcController {

    @RequestMapping("/hello/{id}")
    public ModelAndView hello(@PathVariable("id") String id) {
        Map<String, String> model = new HashMap<>();
        ModelAndView modelAndView = new ModelAndView("hello", model);
        return modelAndView;
    }

}

/src/main/webapp/WEB-INF/jsp/hello.jsp

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="e"
    uri="https://www.owasp.org/index.php/OWASP_Java_Encoder_Project"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
    </head>
    <body>HELLO WORLD
    </body>
</html>

/src/test/java/controller/MvcControllerTest.java

package controller;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = { MvcController.class })
public class MvcControllerTest {

    @Autowired
    private MvcController mvcController;

    private MockMvc mockMvc;

    @Before
    public void init() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/jsp/");
        resolver.setSuffix(".jsp");
        this.mockMvc = MockMvcBuilders.standaloneSetup(mvcController).setViewResolvers(resolver).build();
    }

    @Test
    public void testHello() throws Exception {
        RequestBuilder requestBuilder = MockMvcRequestBuilders.get("/hello/XWQHEDg9e72t");
        ResultActions result = mockMvc.perform(requestBuilder);
        MvcResult mvcResult = result.andReturn();
        MockHttpServletResponse mockHttpServletResponse = mvcResult.getResponse();
        String response = mockHttpServletResponse.getContentAsString();
        assertThat(response).contains("HELLO WORLD");
    }

}

The key word in MockMvc is mock . This framework does not set up a full Servlet container with a JSP engine. As such, it doesn't render the view that your controller returns and the MockHttpServletResponse does not contain a body (for this use case).

You can use MockHttpServletResponse#getForwardedUrl() to get the url of the JSP that the Servlet container would've forwarded the request to, constructed from your view name and the prefix and suffix of your InternalResourceViewResolver .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM