JUnit日期测试中Timestamp JSON格式断言失败问题求助
解决Timestamp格式不匹配导致的断言失败问题
咱先把问题根源理清楚:你代码里的Timestamp对象直接toString的格式是2021-04-29T15:05:09.090235,但接口返回的JSON里,Spring默认的JSON序列化工具Jackson会把Timestamp序列化成带时区偏移的ISO标准格式2021-04-29T13:05:09.090+00:00,两者格式不一致,自然就断言失败了。
给你几个实用的解决方案,按需选择:
方案1:直接用序列化后的字符串作为预期值
既然接口返回的是Jackson序列化后的格式,那咱就提前把timestamp序列化成相同格式的字符串,再用来断言。代码示例:
// 引入Jackson的ObjectMapper import com.fasterxml.jackson.databind.ObjectMapper; // ... 测试代码 ... Timestamp timestamp = Timestamp.valueOf(now); Country country = new Country("France", timestamp); given(countryService.getDetail(anyString())).willReturn(country); // 把timestamp序列化成接口返回的格式字符串 ObjectMapper objectMapper = new ObjectMapper(); String expectedLastUpdate = objectMapper.writeValueAsString(timestamp).replace("\"", ""); // 去掉序列化后自带的引号 mockMvc.perform(MockMvcRequestBuilders.get("/api/country/France")) .andExpect(status().isOk()) .andExpect(jsonPath("country").value("France")) .andExpect(jsonPath("lastUpdate").value(expectedLastUpdate));
方案2:统一全局/实体类的日期序列化格式
如果希望项目里所有日期字段都输出你预期的格式,可以配置Jackson的序列化规则:
方式A:Spring Boot配置文件
在application.properties或application.yml里添加:
# 指定日期格式 spring.jackson.date-format=yyyy-MM-dd'T'HH:mm:ss.SSSSSS # 指定时区(根据你的业务需求调整,比如UTC或者Asia/Shanghai) spring.jackson.time-zone=UTC
方式B:实体类字段注解
如果只想给Country类的lastUpdate字段单独配置,就在字段上加@JsonFormat注解:
import com.fasterxml.jackson.annotation.JsonFormat; import java.sql.Timestamp; public class Country { private String country; @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSSSS", timezone = "UTC") private Timestamp lastUpdate; // 构造器、getter/setter... }
配置完成后,接口返回的lastUpdate格式就和你预期的一致了,直接用timestamp对象断言即可。
方案3:用时间毫秒值断言(最稳妥)
如果不想纠结格式,直接比较时间的本质——毫秒数,这样不管格式怎么变,只要时间正确就会通过断言:
mockMvc.perform(MockMvcRequestBuilders.get("/api/country/France")) .andExpect(status().isOk()) .andExpect(jsonPath("country").value("France")) .andExpect(jsonPath("lastUpdate").value(timestamp.getTime()));
如果接口返回的lastUpdate还是字符串格式,也可以用Hamcrest的匹配器忽略时区差异直接比较时间对象:
import org.hamcrest.Matchers; // ... .andExpect(jsonPath("lastUpdate", Matchers.equalToIgnoringTz(timestamp)))
内容的提问来源于stack exchange,提问作者F3th1
相关产品推荐
相关产品推荐

