Sto utilizzando un URL restful per avviare un processo di back-end di lunga durata (normalmente è su un cron schedule, ma vogliamo la possibilità di eseguirlo manualmente).Test di Spring asyncResult() e jsonPath() insieme
Il codice seguente funziona e vedo il risultato nel browser quando eseguo il test manualmente.
@ResponseBody
@RequestMapping(value = "/trigger/{jobName}", method = RequestMethod.GET)
public Callable<TriggerResult> triggerJob(@PathVariable final String jobName) {
return new Callable<TriggerResult>() {
@Override
public TriggerResult call() throws Exception {
// Code goes here to locate relevant job and kick it off, waiting for result
String message = <result from my job>;
return new TriggerResult(SUCCESS, message);
}
};
}
quando prova questo senza l'Callable
ho usato il codice qui sotto e funziona tutto (ho cambiato il messaggio di errore previsto per semplificare post).
mockMvc.perform(get("/trigger/job/xyz"))
.andExpect(status().isOk())
.andDo(print())
.andExpect(jsonPath("status").value("SUCCESS"))
.andExpect(jsonPath("message").value("A meaningful message appears"));
Quando ho aggiunto il Callable
però non funziona. Ho anche provato di seguito ma non ha funzionato. Qualcun altro ha avuto successo?
mockMvc.perform(get("/trigger/job/xyz"))
.andExpect(status().isOk())
.andDo(print())
.andExpect(request().asyncResult(jsonPath("status").value("SUCCESS")))
.andExpect(request().asyncResult(jsonPath("message").value("A meaningful message appears")));
Di seguito è riportata la parte pertinente dalla mia stampa(). Sembra che mockMvc non possa sbrogliare correttamente Json in questo caso (anche se funziona nel mio browser)? Quando eseguo questa operazione senza Callable
, vedo JSON completo.
MockHttpServletRequest:
HTTP Method = GET
Request URI = /trigger/job/xyz
Parameters = {}
Headers = {}
Handler:
Type = foo.bar.web.controller.TriggerJobController
Method = public java.util.concurrent.Callable<foo.bar.myproject.web.model.TriggerResult> foo.bar.myproject.web.controller.TriggerJobController.triggerJob(java.lang.String)
Async:
Was async started = true
Async result = [email protected]
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
MockHttpServletResponse:
Status = 200
Error message = null
Headers = {}
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
Sarebbe opportuno sottolineare che il metodo 'instanceOf()' fa parte della libreria di Hamcrest. Mi ci è voluto un po 'per scoprirlo e poi inserire l'importazione ** maven ** appropriata. Date un'occhiata a questo esempio [mvc showcase] (https://github.com/spring-projects/spring-mvc-showcase/blob/master/src/test/java/org/springframework/samples/mvc/async/CallableControllerTests .java) aiutato. –
Certo, buon punto. Aggiunto. –
utilizza asyncDispatch() completamente necessario? Sembra interrompere l'incapsulamento del test - che dovrebbe solo sapere quale risultato aspettarsi quando invia un GET a/trigger/job/xyz - per sapere che l'implementazione di quel controller è asincrona –