首页 文章

Spring MVC testframework因HTTP Response 406而失败

提问于
浏览
9

我开始使用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:期望的状态:<200>但是在org.springframework.test.util.AssertionErrors.assertEquals的org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:60)中是:<406> (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)在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)在java.lang.reflect.Method.invoke(Method.java:597)在org.junit.runners.model.FrameworkMethod $ 1.runReflectiveCall(FrameworkMethod.java:45 )org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)at org.junit.ru在org.junit.internal.runners.statements.RunBefores.evaluate的org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)中的nners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)在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)在org.junit.runners.ParentRunner $ 1.schedule(ParentRunner.java :60)在org.junit.runners.ParentRunner.runChildren(ParentRunner) .java:229)org.junit.runners.ParentRunner.access $ 000(ParentRunner.java:50)位于org.springframework.test.context的org.junit.runners.ParentRunner $ 2.evaluate(ParentRunner.java:222) . junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)at org.junit.runners.ParentRunner.run(ParentRunner . Java的:300)在org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)在org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)在组织位于org.eclipse.jdt的org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)的.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) .internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)at or.e.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteT) estRunner.java:390)org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

8 回答

  • 0

    您需要将以下代码添加到spring xml以在jackson中序列化POJO .

    <annotation-driven />
    
  • 0

    有必要同时拥有 @EnableWebMvc.accept(MediaType.APPLICATION_JSON)

  • 14

    您缺少配置xml文件中的 <mvc:annotation-driven /> .

  • 1

    我认为, Spring 天的做事方式是使用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);
    }
    

    (我会对此感兴趣你做的所有进步都是非常新的)

  • 3

    我认为修复方法是以这种方式修改请求:

    this.mockMvc.perform(get("/someurl?someparam=somevalue").contentType(MediaType.APPLICATION_JSON)).andExpect..
    
  • 3

    我刚才遇到了同样的问题,并通过将Controller的返回类型更改为String来解决 . 并直接返回JSON字符串而不是对象 . 它确实有效 .

    Gson gson = new Gson();
    return gson.toJson(dto);
    
  • 0

    如果您有 @Configuration 类,则可以添加 @EnableWebMvc 注释,而不是使用带有 <mvc:annotation-driven /> 的XML配置 .

  • 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>
    

    人们可以很容易地测试上面是否是问题,控制器没有指定任何特殊的东西(例如: @RequestMapping 中没有 produces ),因此不需要任何内容协商:

    @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"); 
    }
    

相关问题