我有一个资源,它返回一个具有
java.time.Instant
属性的对象。
class X {
...
private Instant startDate;
...
}
我正在测试它:
mockMvc.perform(get("/api/x"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.content.[*].startDate").value(hasItem(MY_INSTANT_DATE)));
但是我从 JUnit 得到的是:
Expected: a collection containing <2018-06-08T11:46:50.292Z> but: was <1528458378.397000000>
如何将我的
Instant
日期映射为这种格式?
我通过制作自定义匹配器找到了解决方案:
class DateEquals extends BaseMatcher<Integer> {
private final Date expectedValue;
DateEquals(Date equalArg) {
expectedValue = equalArg;
}
@Override
public boolean matches(Object item) {
Long dateTimeMillis = (Long) item;
return dateTimeMillis.equals(toEpochMillis(expectedValue));
}
@Override
public void describeTo(Description description) {
description.appendValue(" equals to date: " + expectedValue);
}
}
工厂:
public class CustomMatchersFactory {
public static Matcher dateEquals(Date date) {
return is(new DateEquals(date));
}
}
及用法:
.andExpect(jsonPath("$.content.[*].startDate", dateEquals(MY_INSTANT_DATE)));
通常不需要显式映射。如果 Jackson Mapper 被告知将日期写为时间戳,就会发生这种情况。 因此,有两个地方需要检查(因为默认情况下此功能是禁用的):
关于代码,您可以查看这篇 Baeldung 文章,其中显示了 ObjectMapper 调整的可能方法:https://www.baeldung.com/spring-boot-customize-jackson-objectmapper#customizing-the-default-objectmapper
关于应用程序属性。适当的属性是
spring.jackson.serialization.write-dates-as-timestamps
,因此要么检查它是否被禁用,要么您可以为了您的信心而明确禁用它(从潜在原因列表中删除这一点):
对于 *.yaml,您可以通过以下方式禁用它:
spring:
jackson:
serialization:
write-dates-as-timestamps: false
或者如果您使用
*.properties
文件
spring.jackson.serialization.write-dates-as-timestamps=false