MockMvc POST返回400-预期201

时间:2020-07-21 21:50:08

标签: junit5 mockmvc

我正在尝试为@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显示成功的帖子: enter image description here

编辑:我已经更新了OP代码以反映当前状态。仍然有同样的问题。

2 个答案:

答案 0 :(得分:1)

使用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());

答案 1 :(得分:1)

好的,所以我终于弄清楚了我的问题,如果有人遇到同样的问题,我会在这里发布。 @Rieckpil的所有建议都是正确的(我会把他的回答标记为正确),而我遇到的另一个问题是我的模拟动作对象。我有:
base
即使public abstract class Base { public virtual void DoSomething() { ... } } public class Derived : Base { public override void DoSomething() { base.DoSomething(); //Here ... } } 的类型为mockAction.setCreatedOn(LocalDateTime.now()),它在体内的结构也越来越像这样:

createdOn

当我将其作为createdOn变量传递给Postman时,我能够得到有意义的错误LocalDateTime

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