Подтвердить что ты не робот

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

4b9b3361

Ответ 1

Когда я проанализировал ваш код. Я также столкнулся с той же проблемой, но моя проблема в том, что если я даю значение как для первого, так и для последнего имени, это означает, что он работает нормально. но когда я даю только одно значение, значит, он говорит 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);
    }

Ответ 2

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

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

Ответ 3

Если кто-то пришел к этому вопросу в поисках способов добавления нескольких параметров одновременно (в моем случае), вы можете использовать .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())