J'essaie de tester une méthode de mon contrôleur dans une application Spring Boot. Il s'agit d'un point de terminaison post, qui obtient un identifiant dans une demande et le transmet à un service:
@Slf4j
@Controller
public class AdministrationController {
private final AdministrationService administrationService;
@Autowired
public AdministrationController(AdministrationService administrationService) {
this.administrationService = administrationService;
}
@PostMapping("/administration")
public @ResponseBody ResponseEntity<String> deleteByMessageId(String id) {
return new ResponseEntity<>(administrationService.deleteMessageById(id), HttpStatus.OK);
}
}
Le test pour cette méthode du contrôleur:
RunWith(SpringRunner.class)
@WebMvcTest(AdministrationController.class)
public class AdministrationControllerTest {
@Autowired
private MockMvc mvc;
@MockBean
private AdministrationService service;
@Test
public void
deleteByMessageId_whenCalled_thenServiceMethodIsCalledWithRequestParameters() throws Exception {
Object randomObj = new Object() {
public final String id = "1234";
};
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(randomObj);
MvcResult result = mvc.perform(
post("/administration")
.contentType(MediaType.APPLICATION_JSON)
.content(json))
.andExpect(status().isOk())
.andReturn();
verify(service, times(1)).deleteMessageById("1234");
}
}
Lorsque j'exécute ce test, la demande de publication est exécutée, mais avec un corps vide:
MockHttpServletRequest:
HTTP Method = POST
Request URI = /administration
Parameters = {}
Headers = {Content-Type=[application/json]}
Body = <no character encoding set>
Session Attrs = {}
Il semble que, même si j'ai défini le contenu dans mon test, il n'apparaît pas dans la demande que j'envoie ..__ Et, en effet, le test échoue:
Argument(s) are different! Wanted: "1234"
Actual invocation has different arguments: null
Qu'est-ce que j'oublie ici? Comment définir le corps de la demande avec MockMvc?
Essayez d'utiliser .characterEncoding("utf-8"))
:
MvcResult result = mvc.perform(post("/administration")
.contentType(MediaType.APPLICATION_JSON)
.content(json)
.characterEncoding("utf-8"))
.andExpect(status().isOk())
.andReturn();
Une autre option (inspirée de la réponse @ stelios-anastasakis) consiste à fournir un codage de caractères dans l'en-tête Content-Type
:
MvcResult result = mvc.perform(post("/administration")
.contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
.content(json)
.andExpect(status().isOk())
.andReturn();
Notez que nous utilisons MediaType.APPLICATION_JSON_UTF8_VALUE
au lieu de MediaType.APPLICATION_JSON
ici.
Il manque sûrement l'annotation pour le paramètre de votre méthode.
public @ResponseBody ResponseEntity<String> deleteByMessageId(String id)
Devrait être quelque chose comme:
public @ResponseBody ResponseEntity<String> deleteByMessageId(@RequestParam("id") String id)
Si vous souhaitez l'utiliser comme paramètre de requête.
Jetez un oeil à la documentation Spring MVC ici . Bien sûr, l'écriture du test dépend de la façon dont vous vous attendez à l'identifiant ici.