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())
尽管 createdOnLocalDateTime 类型,但它在正文中被解构为如下所示:

"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"])

当我删除它时测试通过了。我保留了所有其他建议。