spring Mock MVC - 添加请求参数进行测试

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17972428/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 06:07:53  来源:igfitidea点击:

Mock MVC - Add Request Parameter to test

springspring-mvcspring-mvc-test

提问by Hymanyesind

I am using spring 3.2 mock mvc to test my controller.My code is

我正在使用 spring 3.2 模拟 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);
        }

and I wrote following test:

我写了以下测试:

@Test public void testGetUserByName() throws Exception {
        String firstName = "Hyman";
        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"));
}

what i get is

我得到的是

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.match(StatusResultMatchers.java:546)
    at org.springframework.test.web.servlet.MockMvc.andExpect(MockMvc.java:141)

Why this happens? Is it right way to pass the @RequestParam

为什么会发生这种情况?传递@RequestParam 是正确的方法吗

回答by muthu

When i analyzed your code. I have also faced the same problem but my problem is if i give value for both first and last name means it is working fine. but when i give only one value means it says 400. anyway use the .andDo(print()) method to find out the error

当我分析你的代码时。我也遇到了同样的问题,但我的问题是,如果我给名字和姓氏都赋值意味着它工作正常。但是当我只给出一个值时,它表示 400。无论如何使用 .andDo(print()) 方法找出错误

public void testGetUserByName() throws Exception {
    String firstName = "Hyman";
    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"));
}

If your problem is org.springframework.web.bind.missingservletrequestparameterexceptionyou have to change your code to

如果您的问题是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);
    }

回答by victortv

If anyone came to this question looking for ways to add multiple parameters at the same time (my case), you can use .paramswith a MultivalueMapinstead of adding each .param:

如果有人来到这个问题,寻找能够在同一时间(我的情况),您可以使用添加多个参数.paramsMultivalueMap而不是增加每个.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())

回答by incomplete-co.de

@ModelAttributeis a Spring mapping of request parameters to a particular object type. so your parameters might look like userClient.usernameand userClient.firstName, etc. as MockMvc imitates a request from a browser, you'll need to pass in the parameters that Spring would use from a form to actually build the UserClientobject.

@ModelAttribute是请求参数到特定对象类型的 Spring 映射。所以你的参数可能看起来像userClient.usernameanduserClient.firstName等,因为 MockMvc 模仿来自浏览器的请求,你需要传入参数,Spring 将从表单中使用这些参数来实际构建UserClient对象。

(i think of ModelAttribute is kind of helper to construct an object from a bunch of fields that are going to come in from a form, but you may want to do some reading to get a better definition)

(我认为 ModelAttribute 是从一堆将从表单中传入的字段构造对象的助手,但您可能需要阅读一些内容以获得更好的定义)