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 contructing 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")); } }
Thank you, it resolved my problem.