MockMvc POST 返回 400 - 期待 201
MockMvc POST returning 400 - expecting 201
我正在尝试为 @PostMapping 编写控制器单元测试,但测试失败
Status expected:<201> but was:<400>
控制器在 Postman 中按预期工作,所以我知道它确实可以工作,但也有一个工作单元测试会很好。
我做错了什么?
测试
@Test
@DisplayName("CREATE NEW ENFORCEMENT ACTION")
void testCreateNewEnforcementAction() throws Exception {
EnforcementAction mockAction = new EnforcementAction();
mockAction.setSystemId(1289);
mockAction.setCurrentStaff("ralbritton");
mockAction.setCurrentStatus("NEEDED");
mockAction.setCreatedOn(LocalDateTime.now());
mockAction.setCreatedBy("ralbritton");
mockAction.setEaType("IF");
mockAction.setEaCode("CAP");
mockAction.setDeleted(false);
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(mockAction);
mockMvc.perform(MockMvcRequestBuilders.post("/api/enforcementactions/action")
.contentType(MediaType.APPLICATION_JSON)
.content(json)
.characterEncoding("utf-8"))
.andExpect(status().isCreated()); //Have also tried this as .isOK() (didn't make a diff)
//.andReturn(); ///Added and removed this line to see if it made a differnce (it did not)
}
正在测试控制器
@PostMapping("/api/enforcementactions/action")
public ResponseEntity<?> createNewEnforcementAction(@RequestBody EnforcementAction newAction) {
service.createEnforcementAction(newAction);
return new ResponseEntity<>(newAction, HttpStatus.CREATED);
}
型号
更新:我在模型中添加以显示字段上没有 Bean 验证
public class EnforcementAction {
private Integer eaId;
private Integer systemId;
private String alternateNumber;
private String systemName;
private Integer tenschdId;
private String currentStaff;
private String currentStatus;
private LocalDate dateActionIssued;
private LocalDate dateActionClosed;
private boolean deleted;
private LocalDateTime createdOn;
private String createdBy;
private LocalDateTime modifiedOn;
private String lastModifiedBy;
private String eaType;
private String eaCode;
private String comment;
private Long daysSinceCreate;
private List<EaStaffHistory> staffAssigned = new ArrayList<>();
private List<EaDocStatusHistory> documentStatus = new ArrayList<>();
private List<EaComments> eaComments = new ArrayList<>();
/** Constructors */
public EnforcementAction() {
}
public EnforcementAction(Integer eaId, Integer systemId, String systemName, Integer tenschdId,
String currentStaff, String currentStatus, Long daysSinceCreate,
String createdBy, String lastModifiedBy, LocalDate dateActionIssued, LocalDate dateActionClosed,
String eaType, String eaCode, LocalDateTime createdOn) {
this.eaId = eaId;
this.systemId = systemId;
this.tenschdId = tenschdId;
this.systemName = systemName;
this.currentStaff = currentStaff;
this.currentStatus = currentStatus;
this.createdBy = createdBy;
this.lastModifiedBy = lastModifiedBy;
this.dateActionClosed = dateActionClosed;
this.dateActionIssued = dateActionIssued;
this.eaType = eaType;
this.eaCode = eaCode;
this.daysSinceCreate = daysSinceCreate;
this.createdOn = createdOn;
}
...getters and setters....
POSTMAN 显示成功 post:
编辑:我更新了 OP 代码以反映当前状态。不过还是有同样的问题。
400
的原因是您将负载发送到控制器的方式。您没有将 Java 对象序列化为 JSON,而是使用它的 .toString()
表示:
.content(String.valueOf(mockAction)))
使用 ObjectMapper
或准备自定义 JSON 字符串:
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(mockAction);
mockMvc.perform(MockMvcRequestBuilders
.post("/api/enforcementactions/action")
.contentType(MediaType.APPLICATION_JSON)
.content(json))
.andExpect(status().isCreated());
好的,所以我终于弄清楚了我的问题,我将其张贴在这里以防其他人遇到同样的问题。虽然@Rieckpil 在他的所有建议中都是正确的(我会将他的回答标记为正确),但我遇到的另一个问题是在我的 mockAction 对象中。我有:
mockAction.setCreatedOn(LocalDateTime.now())
尽管 createdOn
是 LocalDateTime
类型,但它在正文中被解构为如下所示:
"createdOn": {
"dayOfWeek": "WEDNESDAY",
"dayOfYear": 204,
"month": "JULY",
"year": 2020,
"dayOfMonth": 22,
"hour": 12,
"minute": 43,
"monthValue": 7,
"nano": 839000000,
"second": 10,
"chronology": {
"id": "ISO",
"calendarType": "iso8601"
}
}
当我将它作为 createdOn 变量传递给 Postman 时,我能够得到一个有意义的错误 .HttpMessageNotReadableException: JSON parse error: Expected array or string.; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Expected array or string. at [Source: (PushbackInputStream); line: 12, column: 21] (through reference chain: gov.deq.utah.enforcementactions.models.enforcementActions.EnforcementAction["createdOn"])
当我删除它时测试通过了。我保留了所有其他建议。
我正在尝试为 @PostMapping 编写控制器单元测试,但测试失败
Status expected:<201> but was:<400>
控制器在 Postman 中按预期工作,所以我知道它确实可以工作,但也有一个工作单元测试会很好。 我做错了什么?
测试
@Test
@DisplayName("CREATE NEW ENFORCEMENT ACTION")
void testCreateNewEnforcementAction() throws Exception {
EnforcementAction mockAction = new EnforcementAction();
mockAction.setSystemId(1289);
mockAction.setCurrentStaff("ralbritton");
mockAction.setCurrentStatus("NEEDED");
mockAction.setCreatedOn(LocalDateTime.now());
mockAction.setCreatedBy("ralbritton");
mockAction.setEaType("IF");
mockAction.setEaCode("CAP");
mockAction.setDeleted(false);
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(mockAction);
mockMvc.perform(MockMvcRequestBuilders.post("/api/enforcementactions/action")
.contentType(MediaType.APPLICATION_JSON)
.content(json)
.characterEncoding("utf-8"))
.andExpect(status().isCreated()); //Have also tried this as .isOK() (didn't make a diff)
//.andReturn(); ///Added and removed this line to see if it made a differnce (it did not)
}
正在测试控制器
@PostMapping("/api/enforcementactions/action")
public ResponseEntity<?> createNewEnforcementAction(@RequestBody EnforcementAction newAction) {
service.createEnforcementAction(newAction);
return new ResponseEntity<>(newAction, HttpStatus.CREATED);
}
型号 更新:我在模型中添加以显示字段上没有 Bean 验证
public class EnforcementAction {
private Integer eaId;
private Integer systemId;
private String alternateNumber;
private String systemName;
private Integer tenschdId;
private String currentStaff;
private String currentStatus;
private LocalDate dateActionIssued;
private LocalDate dateActionClosed;
private boolean deleted;
private LocalDateTime createdOn;
private String createdBy;
private LocalDateTime modifiedOn;
private String lastModifiedBy;
private String eaType;
private String eaCode;
private String comment;
private Long daysSinceCreate;
private List<EaStaffHistory> staffAssigned = new ArrayList<>();
private List<EaDocStatusHistory> documentStatus = new ArrayList<>();
private List<EaComments> eaComments = new ArrayList<>();
/** Constructors */
public EnforcementAction() {
}
public EnforcementAction(Integer eaId, Integer systemId, String systemName, Integer tenschdId,
String currentStaff, String currentStatus, Long daysSinceCreate,
String createdBy, String lastModifiedBy, LocalDate dateActionIssued, LocalDate dateActionClosed,
String eaType, String eaCode, LocalDateTime createdOn) {
this.eaId = eaId;
this.systemId = systemId;
this.tenschdId = tenschdId;
this.systemName = systemName;
this.currentStaff = currentStaff;
this.currentStatus = currentStatus;
this.createdBy = createdBy;
this.lastModifiedBy = lastModifiedBy;
this.dateActionClosed = dateActionClosed;
this.dateActionIssued = dateActionIssued;
this.eaType = eaType;
this.eaCode = eaCode;
this.daysSinceCreate = daysSinceCreate;
this.createdOn = createdOn;
}
...getters and setters....
POSTMAN 显示成功 post:
编辑:我更新了 OP 代码以反映当前状态。不过还是有同样的问题。
400
的原因是您将负载发送到控制器的方式。您没有将 Java 对象序列化为 JSON,而是使用它的 .toString()
表示:
.content(String.valueOf(mockAction)))
使用 ObjectMapper
或准备自定义 JSON 字符串:
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(mockAction);
mockMvc.perform(MockMvcRequestBuilders
.post("/api/enforcementactions/action")
.contentType(MediaType.APPLICATION_JSON)
.content(json))
.andExpect(status().isCreated());
好的,所以我终于弄清楚了我的问题,我将其张贴在这里以防其他人遇到同样的问题。虽然@Rieckpil 在他的所有建议中都是正确的(我会将他的回答标记为正确),但我遇到的另一个问题是在我的 mockAction 对象中。我有:
mockAction.setCreatedOn(LocalDateTime.now())
尽管 createdOn
是 LocalDateTime
类型,但它在正文中被解构为如下所示:
"createdOn": {
"dayOfWeek": "WEDNESDAY",
"dayOfYear": 204,
"month": "JULY",
"year": 2020,
"dayOfMonth": 22,
"hour": 12,
"minute": 43,
"monthValue": 7,
"nano": 839000000,
"second": 10,
"chronology": {
"id": "ISO",
"calendarType": "iso8601"
}
}
当我将它作为 createdOn 变量传递给 Postman 时,我能够得到一个有意义的错误 .HttpMessageNotReadableException: JSON parse error: Expected array or string.; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Expected array or string. at [Source: (PushbackInputStream); line: 12, column: 21] (through reference chain: gov.deq.utah.enforcementactions.models.enforcementActions.EnforcementAction["createdOn"])
当我删除它时测试通过了。我保留了所有其他建议。