2013-01-02 12 views
8

Ho iniziato a utilizzare il nuovo MVC Testframework di Spring 3.2 e sono rimasto bloccato con l'ottenimento di 406 codici di risposta HTTP per tutti i miei casi di test.SpringFound MVC fallito con HTTP Response 406

Il testcase è semplice semplice

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()); 
    } 

} 

la risorsa corrispondente è

@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 
    } 

} 

Sono sicuro che è a causa di un tipo di supporto sbagliato, ma non riesco a capire perché.

La traccia del TestCase in mancanza:

java.lang.AssertionError: Status expected:<200> but was:<406> at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:60) at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:89) at org.springframework.test.web.servlet.result.StatusResultMatchers$5.match(StatusResultMatchers.java:546) at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:141) at de.yourdelivery.rest.location.LocationResouceTest.testGetLocationByPlzPattern(LocationResouceTest.java:37) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) 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.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) 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.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88) 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)

risposta

0

Il modo primavera di fare le cose è, credo, per usare un HttpResponseEntity, o restituire un modelandview. Per esempio:

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

(Sarei interessato a qualsiasi ulteriore progresso si effettua come il suo tutto abbastanza nuovo)

+0

ok ho controllato che e ancora ottenere una risposta 406.Ho modificato la mia domanda per far rimuovere il metodo 'accept' – MatthiasLaug

+0

. Il risultato è lo stesso con '? Someparam' e' param ("someparam", valore) ' – MatthiasLaug

+0

Non ho una risposta, ma un 406, quindi nessun json ... ma funziona ancora se lo arricciamo – MatthiasLaug

0

penso che la correzione è di modificare la richiesta in questo modo:

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

provato pure, ancora 406 – MatthiasLaug

+0

Provate anche un '.accept', con' MediaType.APPLICATION_JSON' –

+0

già provato anche questo ... ancora 406 – MatthiasLaug

3

Questo potrebbe essere causato da non avere alcuna configurazione MVC nel contesto del test Spring. Quando si utilizza qualcosa come:

@RunWith(SpringJUnit4ClassRunner.class) 
@WebAppConfiguration 
@ContextConfiguration("/test-context.xml") 

... allora che test-context.xml file dovrebbe includere anche cose come:

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

Si può facilmente verificare se quanto precede è il problema, con un controller che non specifica niente di speciale (come ad esempio: non produces in @RequestMapping), e quindi non ha bisogno di alcun negoziazione dei contenuti:

@RequestMapping(value = "/foo", method = RequestMethod.GET) 
@ResponseBody 
public String getFoo() { 
    return "bar"; 
} 

... con:

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

La primavera dovrebbe emettere molti messaggi di errore se fosse così, no? – Raedwald

+0

Io non la penso così, @Raedwald. L'ho postato dopo essermi imbattuto in 406 inaccettabile e poi aver trovato la correzione. Non sono sicuro di avere tracce di stack, ma ne dubito. Durante l'inizializzazione, non vedo perché Spring avrebbe stampato errori per '@ RequestMapping' quando non sapeva ancora quali richieste avrebbe mai ottenuto. E durante una richiesta effettiva semplicemente non sarebbe in grado di mapparla; non ci sono molti errori da stampare lì? Non essere in grado di mappare la richiesta effettiva equivarrebbe alla richiesta di un URL sconosciuto o alla richiesta di utilizzare un metodo HTTP non mappato: una risposta all'errore HTTP senza molto altro? – Arjan

3

È necessario aggiungere il seguente codice a spring xml per serializzare POJO in jackson.

<annotation-driven /> 
0

Ho incontrato lo stesso problema proprio ora e si risolve cambiando il tipo di ritorno del Controller in String. E restituisce una stringa JSON invece di un oggetto direttamente. Funziona.

Gson gson = new Gson(); 
return gson.toJson(dto); 
1

Manca lo <mvc:annotation-driven /> nel file di configurazione xml.

11

Se si dispone di una classe @Configuration, è possibile aggiungere l'annotazione @EnableWebMvc anziché utilizzare una configurazione XML con <mvc:annotation-driven />.

+0

Grazie. Questo ha risolto il mio problema. – dragn

+0

Grazie, l'aggiunta di @EnableWebMvc alla mia classe di test '@ Configuration' ha fatto il trucco! –

+0

Grazie, finalmente ho trovato il mio problema !! –

2

È necessario avere sia @EnableWebMvc e .accept(MediaType.APPLICATION_JSON)

Problemi correlati