7

I could not test page content with spring mvc test because it is empty.

Given simplest possible controller:

@RequestMapping(value = "/home")
public String home(HttpSession session, ModelMap model) {
  return "home";
}

relevant tiles config:

<definition name="base.definition" template="/jsp/view/application.jsp">
  <put-attribute name="header" value="/jsp/view/header.jsp" />
  <put-attribute name="menu" value="/jsp/view/menu.jsp" />
  <put-attribute name="title" value="" />
  <put-attribute name="body" value="" />
  <put-attribute name="footer" value="/jsp/view/footer.jsp" />
</definition>
<definition name="home" extends="base.definition">
  <put-attribute name="title" value="Welcome" />
  <put-attribute name="body" value="/jsp/view/home/list-home.jsp" />
</definition>

Simple list-home.jsp

<p>Welcome</p>

And the test:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration()
@ContextConfiguration(classes = WebTestConfig.class)
public class HomeControllerTest {
  @Autowired
  private WebApplicationContext wac;
  private MockMvc mockMvc;

  @Before
  public void _setup() {
    this.mockMvc =   MockMvcBuilders.webAppContextSetup(this.wac).build();
  }

  @Test
  public void home() throws Exception {
    mockMvc.perform(get("/home"))
        .andDo(print())
        .andExpect(status().isOk())
        .andExpect(forwardedUrl("/jsp/view/application.jsp"))
        .andExpect(content().string("Welcome"));
  }

And it is failing java.lang.AssertionError: Response content expected:<Welcome> but was:<>

the printed out response is the following:

MockHttpServletResponse:
              Status = 200
       Error message = null
             Headers = {}
        Content type = null
                Body = 
       Forwarded URL = /jsp/view/application.jsp
      Redirected URL = null
             Cookies = []

Environment:

  • Spring 3.2
  • Tiles 2
  • Java 6

What have I missed?

NB: The code is working in Tomcat with real browser.

takacsot
  • 1,727
  • 2
  • 19
  • 30
  • 2
    You cannot test jsp (content) with spring mvc test. It is even harder if there is tiles involved. I don't find the documentation link or source but it is not possible. – meistermeier Mar 09 '15 at 15:42
  • 2
    The documentation: http://docs.spring.io/spring-framework/docs/3.2.0.BUILD-SNAPSHOT/reference/htmlsingle/#spring-mvc-test-framework with following line `For the most part everything should work as it does at runtime with the exception of JSP rendering, which is not available outside a Servlet container` – meistermeier Mar 09 '15 at 15:48
  • So testing process presented in http://www.infoq.com/presentations/spring-mvc-test-htmlunit is not available before Spring 4.x. Am I right? – takacsot Mar 10 '15 at 10:49
  • Sorry for the confusing link url. It is still valid for Spring 4. I just took a glance into the presentation and the related sources on github. It looks like they don't really test the jsp with pure spring mvc test but use (instrument) HtmlUnit to check the outcome. In my opinion this kind of tests do the step from simple unit testing to (something like) system / integration tests because you are leaving the internals of your code by testing it from the outside (HtmlUnit). – meistermeier Mar 10 '15 at 11:20
  • To get a solution for your test, you should consider taking a first step by testing a single controller with a MockMvcBuilders#standaloneSetup. Here you can provide a ViewResolver (e.g. Jackson for json) and check the content. – meistermeier Mar 10 '15 at 11:26
  • With `@ResponseBody` annotated controllers it is working fine. I got back proper JSON strings in body. – takacsot Mar 10 '15 at 14:07

1 Answers1

9

You cannot write assertions for the content of a JSP page because JSP pages are rendered by a servlet container and Spring MVC Test doesn't run a servlet container. You can only verify that the view name is correct and/or the request is forwarded to the correct url.

However, you can write assertions for the content of your views if you use a view technology that doesn't require a servlet container (such as Velocity or Thymeleaf).

pkainulainen
  • 1,458
  • 1
  • 19
  • 51