104 votes

Mock MVC - Ajouter un paramètre de requête au test

J'utilise spring 3.2 mock mvc pour tester mon contrôleur. mon code est le suivant

 @Autowired
     private Client client;

     @RequestMapping(value = "/user", method = RequestMethod.GET)
        public String initUserSearchForm(ModelMap modelMap) {
            User user = new User();
            modelMap.addAttribute("User", user);
            return "user";
        }

        @RequestMapping(value = "/byName", method = RequestMethod.GET)
        @ResponseStatus(HttpStatus.OK)
        public
        @ResponseBody
        String getUserByName(
           @RequestParam("firstName") String firstName,
           @RequestParam("lastName") String lastName,
           @ModelAttribute("userClientObject") UserClient userClient) {
            return client.getUserByName(userClient, firstName, lastName);
        }

et j'ai écrit le test suivant :

@Test public void testGetUserByName() throws Exception {
        String firstName = "Jack";
        String lastName = "s";       
        this.userClientObject = client.createClient();
        mockMvc.perform(get("/byName")
                .sessionAttr("userClientObject", this.userClientObject)
                .param("firstName", firstName)
                .param("lastName", lastName)               
        ).andExpect(status().isOk())
                .andExpect(content().contentType("application/json"))
                .andExpect(jsonPath("$[0].id").exists())
                .andExpect(jsonPath("$[0].fn").value("Marge"));
}

Ce que j'obtiens est

java.lang.AssertionError: Status expected:<200> but was:<400>
    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)

Pourquoi cela arrive-t-il ? Est-ce la bonne façon de passer le @RequestParam

139voto

muthu Points 1980

Quand j'ai analysé votre code. J'ai également rencontré le même problème, mais mon problème est que si je donne une valeur pour les deux noms et prénoms, cela fonctionne bien. Mais si je ne donne qu'une seule valeur, cela indique 400. De toute façon, utilisez la méthode .andDo(print()) pour trouver l'erreur.

public void testGetUserByName() throws Exception {
    String firstName = "Jack";
    String lastName = "s";       
    this.userClientObject = client.createClient();
    mockMvc.perform(get("/byName")
            .sessionAttr("userClientObject", this.userClientObject)
            .param("firstName", firstName)
            .param("lastName", lastName)               
    ).andDo(print())
     .andExpect(status().isOk())
            .andExpect(content().contentType("application/json"))
            .andExpect(jsonPath("$[0].id").exists())
            .andExpect(jsonPath("$[0].fn").value("Marge"));
}

Si votre problème est org.springframework.web.bind.missingservletrequestparameterexception vous devez modifier votre code pour

@RequestMapping(value = "/byName", method = RequestMethod.GET)
    @ResponseStatus(HttpStatus.OK)
    public
    @ResponseBody
    String getUserByName(
        @RequestParam( value="firstName",required = false) String firstName,
        @RequestParam(value="lastName",required = false) String lastName, 
        @ModelAttribute("userClientObject") UserClient userClient)
    {

        return client.getUserByName(userClient, firstName, lastName);
    }

14voto

Victor Val Points 612

Si quelqu'un est venu à cette question en cherchant des moyens d'ajouter plusieurs paramètres en même temps (mon cas), vous pouvez utiliser .params avec un MultivalueMap au lieu d'ajouter chaque .param :

LinkedMultiValueMap<String, String> requestParams = new LinkedMultiValueMap<>()
requestParams.add("id", "1");
requestParams.add("name", "john");
requestParams.add("age", "30");

mockMvc.perform(get("my/endpoint").params(requestParams)).andExpect(status().isOk())

0voto

incomplete-co.de Points 2087

@ModelAttribute est un mappage de Spring des paramètres de requête vers un type d'objet particulier. Ainsi, vos paramètres pourraient ressembler à userClient.username y userClient.firstName etc. Comme MockMvc imite une requête provenant d'un navigateur, vous devrez transmettre les paramètres que Spring utiliserait à partir d'un formulaire pour construire réellement l'interface utilisateur. UserClient objet.

(Je pense que ModelAttribute est une sorte d'aide pour construire un objet à partir d'un tas de champs qui vont venir d'un formulaire, mais vous pouvez vouloir faire quelques lectures pour obtenir une meilleure définition).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X