I am doing unit tests of a web application that I am developing and I have encountered a problem when testing some of the functions of the controller.
Basically I am creating a mockMvc and I want to pass it an object that I previously created. The code is this:
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())
;
The controller receives two objects per parameter. This controller is the one that uses the view to create a new record of the indicated object.
@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";
}
I have verified that if in the addConnection()
method I put the @RequestBody
tag, the test works for me but it stops working from the Web. How can I simulate the object the controller receives with the mockMvc?
From the view, I'm using "thymeleaf" to generate new records from HTML form. The source is like this:
<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>
Thank you very much in advance.
Apparently, the HTML form sends the values as parameters to the controller. When changing the mockMvc to pass the values as parameters instead of as json body, as commented by @M. Deinum has fixed the error.
The code would be as follows:
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())
;
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments