MockMvc - 将对象从模拟传递到控制器
MockMvc - Pass an object from the mock to the controller
我正在对正在开发的 Web 应用程序进行单元测试,在测试控制器的某些功能时遇到了问题。
基本上我正在创建一个 mockMvc,我想将我之前创建的对象传递给它。代码是这样的:
Connection connection1 = new Connection();
connection1.setStatus(Status.IN);
connection1.setConnectionId("countingCamera1Conn");
connection1.setPath("urlPath");
connection1.setUsername("userName");
when(connectionRepoMock.existsById(anyString())).thenReturn(true);
//then
mockMvc.perform(post("/model/connection")
.content(asJsonString(connection1))
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isCreated())
;
控制器每个参数接收两个对象。此控制器是使用视图创建指定对象的新记录的控制器。
@PostMapping("model/connection")
public String addConnection(Connection connection, Model model) {
checkRole(model);
if(!checkElement(connection,model))
return "error";
if(controllerRepo.existsById(connection.getConnectionId())) {
model.addAttribute("errorMsg", "The Id already exists, please try another one");
return "error";
}
controllerRepo.save(connection);
return "redirect:/model/connection";
}
我已经验证,如果我在 addConnection()
方法中放置了 @RequestBody
标记,该测试对我有效,但它在 Web 上停止工作。如何使用 mockMvc 模拟控制器接收的对象?
从视图上看,我正在使用 "thymeleaf" 从 HTML 表单生成新记录。来源是这样的:
<div class="form-group row px-md-4">
<h1>Connection</h1>
<div class="col-sm-1 py-sm-1">
<button class="btn btn-primary" type="button" data-toggle="modal"
data-target="#addConnection" value="Add a connection" rel="tooltip"
title="Add a new connection">
<i class="fa fa-plus"></i>
</button>
</div>
<!-- Modal -->
<div class="modal fade" id="addConnection" tabindex="-1"
role="dialog" aria-labelledby="#addConnectionTitle"
aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addConnectionTitle">Add a
connection</h5>
<button type="button" class="close" data-dismiss="modal"
aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form th:action="@{/model/connection}" th:object="${connection}"
method="post">
<div class="form-group">
<label for="id_input" class="col-form-label"><b>ID:
*</b></label> <input type="text" class="form-control" id="id_input"
th:field="*{connectionId}" placeholder="Enter ID" required>
</div>
<div class="form-group">
<label for="path_input" class="col-form-label"><b>Path:
*</b></label> <input type="text" class="form-control" id="path_input"
th:field="*{path}" placeholder="Enter Path" required>
</div>
<div class="form-group">
<label for="username_input" class="col-form-label"><b>User
name: *</b></label> <input type="text" class="form-control"
id="username_input" th:field="*{username}"
placeholder="Enter User">
</div>
<div class="form-group">
<label for="pwd_input" class="col-form-label"><b>Password:
*</b></label> <input type="password" class="form-control" id="pwd_input"
th:field="*{pwd}" placeholder="Enter Password">
</div>
<div class="form-group">
<label for="status_input" class="col-form-label"><b>Status:
*</b></label> <select class="form-control" id="status_input"
th:field="*{status}">
<option
th:each="status : ${T(com.ascspain.iothub.model.Status).values()}"
th:value="${status}" th:text="${status}"></option>
</select>
</div>
<label class="text-muted px-sm-1"><small>Check
that all credentials with * are filled</small></label> <br>
<div class="modal-footer">
<button type="button" class="btn btn-secondary"
data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Save
changes</button>
</div>
</form>
</div>
</div>
</div>
</div>
<!-- End of Modal -->
</div>
非常感谢您。
你应该使用@RequestBody。为什么它停止工作?请解释问题
显然,HTML表单将值作为参数发送给控制器。当更改 mockMvc 以将值作为参数而不是作为 json 主体传递时,正如@M 所评论的那样。 Deinum 已修复错误。
代码如下:
mockMvc.perform(post("/model/connection")
.param("connectionId", "countingCamera1Conn")
.param("path", "urlPath")
.param("status", "IN")
.param("username", "username")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isCreated())
;
我正在对正在开发的 Web 应用程序进行单元测试,在测试控制器的某些功能时遇到了问题。
基本上我正在创建一个 mockMvc,我想将我之前创建的对象传递给它。代码是这样的:
Connection connection1 = new Connection();
connection1.setStatus(Status.IN);
connection1.setConnectionId("countingCamera1Conn");
connection1.setPath("urlPath");
connection1.setUsername("userName");
when(connectionRepoMock.existsById(anyString())).thenReturn(true);
//then
mockMvc.perform(post("/model/connection")
.content(asJsonString(connection1))
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isCreated())
;
控制器每个参数接收两个对象。此控制器是使用视图创建指定对象的新记录的控制器。
@PostMapping("model/connection")
public String addConnection(Connection connection, Model model) {
checkRole(model);
if(!checkElement(connection,model))
return "error";
if(controllerRepo.existsById(connection.getConnectionId())) {
model.addAttribute("errorMsg", "The Id already exists, please try another one");
return "error";
}
controllerRepo.save(connection);
return "redirect:/model/connection";
}
我已经验证,如果我在 addConnection()
方法中放置了 @RequestBody
标记,该测试对我有效,但它在 Web 上停止工作。如何使用 mockMvc 模拟控制器接收的对象?
从视图上看,我正在使用 "thymeleaf" 从 HTML 表单生成新记录。来源是这样的:
<div class="form-group row px-md-4">
<h1>Connection</h1>
<div class="col-sm-1 py-sm-1">
<button class="btn btn-primary" type="button" data-toggle="modal"
data-target="#addConnection" value="Add a connection" rel="tooltip"
title="Add a new connection">
<i class="fa fa-plus"></i>
</button>
</div>
<!-- Modal -->
<div class="modal fade" id="addConnection" tabindex="-1"
role="dialog" aria-labelledby="#addConnectionTitle"
aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addConnectionTitle">Add a
connection</h5>
<button type="button" class="close" data-dismiss="modal"
aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form th:action="@{/model/connection}" th:object="${connection}"
method="post">
<div class="form-group">
<label for="id_input" class="col-form-label"><b>ID:
*</b></label> <input type="text" class="form-control" id="id_input"
th:field="*{connectionId}" placeholder="Enter ID" required>
</div>
<div class="form-group">
<label for="path_input" class="col-form-label"><b>Path:
*</b></label> <input type="text" class="form-control" id="path_input"
th:field="*{path}" placeholder="Enter Path" required>
</div>
<div class="form-group">
<label for="username_input" class="col-form-label"><b>User
name: *</b></label> <input type="text" class="form-control"
id="username_input" th:field="*{username}"
placeholder="Enter User">
</div>
<div class="form-group">
<label for="pwd_input" class="col-form-label"><b>Password:
*</b></label> <input type="password" class="form-control" id="pwd_input"
th:field="*{pwd}" placeholder="Enter Password">
</div>
<div class="form-group">
<label for="status_input" class="col-form-label"><b>Status:
*</b></label> <select class="form-control" id="status_input"
th:field="*{status}">
<option
th:each="status : ${T(com.ascspain.iothub.model.Status).values()}"
th:value="${status}" th:text="${status}"></option>
</select>
</div>
<label class="text-muted px-sm-1"><small>Check
that all credentials with * are filled</small></label> <br>
<div class="modal-footer">
<button type="button" class="btn btn-secondary"
data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Save
changes</button>
</div>
</form>
</div>
</div>
</div>
</div>
<!-- End of Modal -->
</div>
非常感谢您。
你应该使用@RequestBody。为什么它停止工作?请解释问题
显然,HTML表单将值作为参数发送给控制器。当更改 mockMvc 以将值作为参数而不是作为 json 主体传递时,正如@M 所评论的那样。 Deinum 已修复错误。
代码如下:
mockMvc.perform(post("/model/connection")
.param("connectionId", "countingCamera1Conn")
.param("path", "urlPath")
.param("status", "IN")
.param("username", "username")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isCreated())
;