Mock MVC — добавьте параметр запроса для тестирования

Я использую Spring 3.2 mock mvc для проверки моего контроллера. Мой код

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

и я написал следующий тест:

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

что я получаю

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)

Почему это происходит? Правильно ли передать @RequestParam


person jackyesind    schedule 31.07.2013    source источник


Ответы (3)


Когда я проанализировал ваш код. Я также столкнулся с той же проблемой, но моя проблема в том, что если я даю значение как для имени, так и для фамилии, это означает, что он работает нормально. но когда я даю только одно значение, это означает, что он говорит 400. в любом случае используйте метод .andDo(print()), чтобы узнать ошибку

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

Если ваша проблема org.springframework.web.bind.missingservletrequestparameterexception, вы должны изменить свой код на

@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);
    }
person muthu    schedule 01.08.2013
comment
Я написал тот же код, но у меня проблема с атрибутом модели. пожалуйста, прочитайте stackoverflow.com/questions/19427341/ - person gstackoverflow; 17.10.2013
comment
Обратите внимание, print() — это метод класса MockMvcResultHandlers. - person WildDev; 04.11.2015

Если кто-то пришел к этому вопросу, ища способы добавить несколько параметров одновременно (мой случай), вы можете использовать .params с MultivalueMap вместо добавления каждого .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())
person victortv    schedule 30.09.2019

@ModelAttribute — это сопоставление Spring параметров запроса с конкретным типом объекта. поэтому ваши параметры могут выглядеть как userClient.username и userClient.firstName и т. д., поскольку MockMvc имитирует запрос из браузера, вам нужно будет передать параметры, которые Spring будет использовать из формы для фактического создания объекта UserClient.

(я думаю, что ModelAttribute является своего рода помощником для создания объекта из набора полей, которые будут поступать из формы, но вы можете немного прочитать, чтобы получить лучшее определение)

person incomplete-co.de    schedule 31.07.2013
comment
Раньше я использовал ModelAttribute, это не было проблемой. Я запутался с тем, как отправить @RequestParam - person jackyesind; 01.08.2013