我开始使用Spring 3.2的新MVC Testframework,并且无法为我的所有测试用例获取406个HTTP响应代码。
测试用例很简单
public class LocationResouceTest {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
@Test
public void testGetLocationByPlzPattern() throws Exception {
// here I need to define the media type as a static var from MediaType
this.mockMvc.perform(get("/someurl?someparam=somevalue")).andExpect(status().isOk());
}
}
相应的资源是
@Controller
// here I need to define the media type as string
@RequestMapping(value = "/someurl", produces = "application/json; charset=UTF-8")
public class LocationResource {
@ResponseBody
@RequestMapping(method = RequestMethod.GET)
public ArrayList<DTO> getAllIndex(@RequestParam("someparam") String param) {
return ... //the list of DTO classes is transformed to json just fine if called with curl
}
}
我确信这是因为媒体类型不对,但我无法弄清楚原因。
失败的测试用例的痕迹:
java.lang.AssertionError:期望的状态:&lt; 200&gt;但是:&lt; 406&gt;在 org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:60) 在 org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:89) 在 org.springframework.test.web.servlet.result.StatusResultMatchers $ 5.match(StatusResultMatchers.java:546) 在 org.springframework.test.web.servlet.MockMvc $ 1.andExpect(MockMvc.java:141) 在 de.yourdelivery.rest.location.LocationResouceTest.testGetLocationByPlzPattern(LocationResouceTest.java:37) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 在java.lang.reflect.Method.invoke(Method.java:597)at org.junit.runners.model.FrameworkMethod $ 1.runReflectiveCall(FrameworkMethod.java:45) 在 org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 在 org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42) 在 org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 在 org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) 在 org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74) 在 org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83) 在 org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72) 在 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231) 在 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88) 在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 at org.junit.runners.ParentRunner.access $ 000(ParentRunner.java:50)at org.junit.runners.ParentRunner $ 2.evaluate(ParentRunner.java:222)at at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 在 org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71) 在org.junit.runners.ParentRunner.run(ParentRunner.java:300)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174) 在 org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 在 org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 在 org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 在 org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 在 org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 在 org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
答案 0 :(得分:15)
如果您有@Configuration
课程,则可以添加。{
@EnableWebMvc
注释而不是使用<mvc:annotation-driven />
的XML配置。
答案 1 :(得分:3)
这可能是由Spring测试上下文中没有任何MVC配置引起的。使用类似的东西时:
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration("/test-context.xml")
...然后test-context.xml
文件还应包含以下内容:
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager">
<mvc:message-converters>
<bean id="..." class=
"org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
<bean id="..."
class="org.springframework.http.converter.StringHttpMessageConverter"/>
<bean id="..."
class="org.springframework.http.converter.FormHttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
<bean id="contentNegotiationManager"
class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="defaultContentType" value="application/json" />
<property name="mediaTypes">
<value>
json=application/json
xml=application/xml
</value>
</property>
</bean>
可以轻松测试以上是否存在问题,控制器没有指定任何特殊内容(例如:produces
中没有@RequestMapping
),因此不需要任何内容协商:
@RequestMapping(value = "/foo", method = RequestMethod.GET)
@ResponseBody
public String getFoo() {
return "bar";
}
...与:
@Test
public void getFoo() throws Exception {
MvcResult result =
this.mockMvc.perform(get("/foo").accept(MediaType.TEXT_PLAIN))
.andExpect(status().isOk())
.andReturn();
Assert.assertEquals(result.getResponse().getContentAsString(), "bar");
}
答案 2 :(得分:3)
您需要将以下代码添加到spring xml中以在jackson中序列化POJO。
<annotation-driven />
答案 3 :(得分:3)
必须同时拥有@EnableWebMvc
和.accept(MediaType.APPLICATION_JSON)
答案 4 :(得分:1)
您缺少配置xml文件中的<mvc:annotation-driven />
。
答案 5 :(得分:0)
我认为,春天的做事方式是使用HttpResponseEntity,或者返回一个模式视图。 例如:
@ResponseBody
ResponseEntity<String> getFoo() {
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setContentType(MediaType.APPLICATION_JSON);
String test = "{\"foo\":{\"title\": \"Stack\"}}";
return new ResponseEntity<String>(test, responseHeaders, HttpStatus.OK);
}
(我会对你所做的任何进一步的进展感兴趣)
答案 6 :(得分:0)
我认为修复方法是以这种方式修改请求:
this.mockMvc.perform(get("/someurl?someparam=somevalue").contentType(MediaType.APPLICATION_JSON)).andExpect..
答案 7 :(得分:-1)
我刚才遇到了同样的问题,并通过将Controller的返回类型更改为String来解决。 并直接返回JSON字符串而不是对象。它确实有效。
Gson gson = new Gson();
return gson.toJson(dto);