PROBLEM
Let’s assume we want to test this controller:-
@Controller
@RequestMapping(value = "/help")
public class HelpController {
@RequestMapping(method = RequestMethod.GET)
public String main() {
return "help";
}
}
Here’s the test file:-
public class HelpControllerTest {
private MockMvc mockMvc;
@Before
public void setup() {
mockMvc = MockMvcBuilders.standaloneSetup(new HelpController()).build();
}
@Test
public void main() throws Exception {
mockMvc.perform(get("/help"))
.andExpect(status().isOk())
.andExpect(view().name("help"));
}
}
When executing this test, we get the following error:-
javax.servlet.ServletException: Circular view path [help]: would dispatch
back to the current handler URL [/help] again. Check your ViewResolver
setup! (Hint: This may be the result of an unspecified view, due to default
view name generation.)
at org.springframework.web.servlet.view.InternalResourceView.prepareForRendering(InternalResourceView.java:263)
at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:186)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:266)
SOLUTION
The reason this is happening is because the uri “/help” matches the returned view name “help” and we didn’t set a ViewResolver
when constructing the standalone MockMvc
. Since MockMvcBuilders.standaloneSetup(...)
doesn’t load Spring configuration, the Spring MVC configuration under WEB-INF/spring-servlet.xml
will not get loaded too.
A typical WEB-INF/spring-servlet.xml
looks something like this:-
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
<context:component-scan base-package="edu.mayo.requestportal.controller"/>
<mvc:annotation-driven/>
<mvc:resources location="/resources/" mapping="/resources/**"/>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/view/"/>
<property name="suffix" value=".jsp"/>
</bean>
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="messages"/>
</bean>
</beans>
To fix this, we need to defined a ViewResolver
that mimics the configuration defined under WEB-INF/spring-servlet.xml
in the test file:-
public class HelpControllerTest {
private MockMvc mockMvc;
@Before
public void setup() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/jsp/view/");
viewResolver.setSuffix(".jsp");
mockMvc = MockMvcBuilders.standaloneSetup(new HelpController())
.setViewResolvers(viewResolver)
.build();
}
@Test
public void main() throws Exception {
mockMvc.perform(get("/help"))
.andExpect(status().isOk())
.andExpect(view().name("help"));
}
}
Leave a Reply