模拟 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 的正确方法吗

222516 次浏览

@ModelAttribute is a Spring mapping of request parameters to a particular object type. so your parameters might look like userClient.username and 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 UserClient object.

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

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

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

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

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

If anyone came to this question looking for ways to add multiple parameters at the same time (my case), you can use .params with a MultivalueMap instead of adding each .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())