web-dev-qa-db-fra.com

Test du contrôleur de ressort avec la méthode post MockMvc

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?

4
handris

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

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.

2
Slava Semushin

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. 

0
galovics