MockMvc 在 RestController 测试中使用空字段保存 Json

MockMvc saves Json with null fields in RestController test

背景

我正在 Spring Boot 中开发小型 REST 应用程序。我想执行测试控制器 (POST.METHOD) 将新对象添加到数据库。

问题

我通过构造函数创建新实体,并在我的对象中指定字段。然后我通过 MockMvc 保存这个对象。还有一个问题,MockMvc 保存了我的对象,但是所有字段都是 null 或 false。控制器使用的服务已经过测试并且可以正常工作

代码

控制器:

    @RestController
    public class ParkingMeterController {

    @Autowired
    ParkingMeterService parkingMeterService;

    @PostMapping("parking-meter")
    public ParkingMeter addParkingMeter(){
        ParkingMeter parkingMeter = new ParkingMeter();
        return parkingMeterService.addNewParkingMeter(parkingMeter);
    }

实体:

    @Entity
    @Component
    @Data
    public class ParkingMeter {

    @Id
    @GeneratedValue
    private long id;
    private boolean occupied = false;
    private Timestamp startTime;
    private Timestamp endTime;

    public ParkingMeter() {
    }

    public ParkingMeter(boolean occupied, Timestamp startTime, Timestamp endTime) {
        this.occupied = occupied;
        this.startTime = startTime;
        this.endTime = endTime;
    }
}

测试class:

    @RunWith(SpringRunner.class)
    @SpringBootTest
    @AutoConfigureMockMvc
    public class ParkingMeterControllerTest {

    @Autowired
    private MockMvc mvc;
    @Autowired
    ParkingMeterService parkingMeterService;

    @Test
    public void shouldAddNewParkingMeter() throws Exception {
        ParkingMeter parkingMeter = new ParkingMeter(true, new Timestamp(0), new Timestamp(5000));
        String json = new Gson().toJson(parkingMeter);
        System.out.println(json);

        mvc.perform(post("/parking-meter/")
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .content(json)
                .accept(MediaType.APPLICATION_JSON_UTF8))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.id", is(3)))
                .andExpect(jsonPath("$.startTime", is(new Timestamp(0))));
    }

系统输出打印结果:

{"id":0,"occupied":true,"startTime":"Jan 1, 1970 1:00:00 AM","endTime":"Jan 1, 1970 1:00:05 AM"}

MockServletResponse:

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = {Content-Type=[application/json;charset=UTF-8]}
     Content type = application/json;charset=UTF-8
             Body = {"id":3,"occupied":false,"startTime":null,"endTime":null}
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

如你所见。在 Mock servlet resposne 中,我们可以看到带有 null 和 false 字段的 Body,这与我定义的不同。

提前致谢。

猜猜,问题在于您以日期格式(使用 Gson 映射器)序列化时间戳,但以其他格式反序列化它(比如使用 Spring 默认 Jackson 映射器)。

有很多方法可以设置数据类型 serialization/deserialization,但我建议您将 json 正文值直接设置为 String 格式期待收到。例如:

String json = "{\"id\":0,\"occupied\":true,\"startTime\":\"0000000000000\",\"endTime\":\"0000000005000\"}"

这种方法将保证您的测试也会检查 serialization/deserialization 个问题!