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 个问题!
背景
我正在 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 个问题!