We are trying to configure Spring-Test-MVC for our Spring-MVC web application. We started using freemarker and everything was fine. We decided against this, although now we are trying to configure it using JSP. When the test application is deployed to Tomcat, it works. When we run a simple test:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(loader = WebContextLoader.class, locations = { "file:src/main/webapp/WEB-INF/servlet-context.xml" }) public class SkelletonTest { @Inject private MockMvc mockMvc; @Test public void homeTest() throws Exception { mockMvc.perform(get("/")).andExpect(status().isOk()) .andExpect(content().type("text/html;charset=ISO-8859-1")) .andExpect(content().string(containsString("Hello World!"))); }
he says: content type not set , or if this is deleted, the content will be empty. However, the controller will be called, so the display should work.
So, this strongly suggests that the view is not displayed for our tests, but I don’t know which installation I could skip.
Here is our servlet-context.xml:
<context:component-scan base-package="package.to.controllers" /> <mvc:annotation-driven /> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <property name="exposeContextBeansAsAttributes" value="true" /> <property name="prefix" value="/views/" /> <property name="suffix" value=".jsp" /> </bean>
WebContextLoader:
public class WebContextLoader extends GenericWebContextLoader { public WebContextLoader() { super("src/main/webapp", false); } }
GenericWebContextLoader is the original Spring -test-mvc.
MockMvc gets the installation as a Bean as follows:
@Configuration public class TestConfig { @Inject private WebApplicationContext wac; @Bean public MockMvc create(){ return (MockMvcBuilders.webApplicationContextSetup(this.wac).build()); } }
So, to set up. web.xml is not used by the testing platform and does not matter since it worked before.
I think that in the servlet context there should be an additional configuration. It loads, I checked, but so far for the deployed Tomcat application it is important that I set it for the prefix and suffix, it will simply be ignored by the test.
Not sure how error tracing will help, but here it is:
java.lang.AssertionError: Content type not set at org.springframework.test.web.AssertionErrors.fail(AssertionErrors.java:35) at org.springframework.test.web.AssertionErrors.assertTrue(AssertionErrors.java:57) at org.springframework.test.web.server.result.ContentResultMatchers$1.match(ContentResultMatchers.java:59) at org.springframework.test.web.server.MockMvc$1.andExpect(MockMvc.java:84) at our.package.SkelletonTest.homeTest(SkelletonTest.java:30) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71) at org.junit.runners.ParentRunner.run(ParentRunner.java:300) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
And test output:
2012-06-15 10:41:04 TestContextManager [INFO] @TestExecutionListeners is not present for class [class package.to.test.SkelletonTest]: using defaults. 2012-06-15 10:41:05 XmlBeanDefinitionReader [INFO] Loading XML bean definitions from URL [file:src/main/webapp/WEB-INF/servlet-context.xml] 2012-06-15 10:41:05 ClassPathBeanDefinitionScanner [INFO] JSR-330 'javax.inject.Named' annotation found and supported for component scanning 2012-06-15 10:41:05 GenericWebApplicationContext [INFO] Refreshing org.springframework.web.context.support.GenericWebApplicationContext@158539f: startup date [Fri Jun 15 10:41:05 CEST 2012]; root of context hierarchy 2012-06-15 10:41:05 AutowiredAnnotationBeanPostProcessor [INFO] JSR-330 'javax.inject.Inject' annotation found and supported for autowiring 2012-06-15 10:41:05 DefaultListableBeanFactory [INFO] Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@c64bc2: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,testConfig,freemarkerController,homeController,tableService,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
So thanks for any suggestions that will help me find the problem!
Btw: I didn't want this to get bigger, so I skipped pom. We are using Spring 3.1, Spring -test-mvc 1.0.0..BUILD-SNAPSHOT, jsp-ap 2.2, jstl 1.2, ... If you need to know more, I will try to download it somewhere ...
Edit
Please let me know if you need more information or why you cannot answer my question. Actually, you need to figure this out, and I have no idea where to start. Therefore, any thoughts or comments are also welcome.
Edit2
The printing method is used with the following output:
MockHttpServletRequest: HTTP Method = GET Request URI = / Parameters = {} Headers = {} Handler: Type = package.to.controller.HomeController Method = public org.springframework.web.servlet.ModelAndView package.to.controller.HomeController.index() Resolved Exception: Type = null ModelAndView: View name = index View = null Attribute = welcome value = Hello World! FlashMap: MockHttpServletResponse: Status = 200 Error message = null Headers = {} Content type = null Body = Forwarded URL = /views/index.jsp Redirected URL = null Cookies = []
Which only shows the problem better, but not the solution ...
Edit3
The following has just been revealed:
JSP requires a servlet container. So it seems that I cannot check my pages this way ... If anyone knows how to get around this problem, please let me know ..