Spring Boot升级至2.7.3后JavaTimeModule注册验证失败求助
我把Spring Boot应用从2.3版本升级到2.7.3后,原本验证工具类中ObjectMapper是否注册JavaTimeModule的测试用例跑失败了。工具类代码如下:
static { mapper = new ObjectMapper(); mapper.registerModule(new JavaTimeModule()); mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); } public static ObjectMapper getObjectMapper() { return mapper; }
测试用例尝试断言注册的模块ID包含JavaTimeModule的类全名:
@Test public void returnsObjectMapper() { ObjectMapper objectMapper = Util.getObjectMapper(); Set<Object> registeredModuleIds = objectMapper.getRegisteredModuleIds(); assertThat(registeredModuleIds).contains(JavaTimeModule.class.getName()); }
运行测试后报错:
java.lang.AssertionError: Expecting UnmodifiableSet:
["jackson-datatype-jsr310"] to contain:
["com.fasterxml.jackson.datatype.jsr310.JavaTimeModule"] but could not
find the following element(s):
["com.fasterxml.jackson.datatype.jsr310.JavaTimeModule"]
问题原因
Spring Boot 2.7.x对应的Jackson版本是2.13.x,这个版本里JavaTimeModule的getId()方法返回值做了变更——从原来的类全限定名改成了模块的artifact ID(即jackson-datatype-jsr310),所以getRegisteredModuleIds()返回的集合里不再包含类全名,导致原有断言失败。
解决办法
方案1:改用模块artifact ID断言
直接修改测试用例中的断言内容,匹配新的模块ID:
@Test public void returnsObjectMapper() { ObjectMapper objectMapper = Util.getObjectMapper(); Set<Object> registeredModuleIds = objectMapper.getRegisteredModuleIds(); assertThat(registeredModuleIds).contains("jackson-datatype-jsr310"); }
方案2:检查模块实例(更可靠)
如果想要避免后续版本变更带来的类似问题,可以直接遍历已注册的模块,验证是否存在JavaTimeModule实例:
@Test public void returnsObjectMapper() { ObjectMapper objectMapper = Util.getObjectMapper(); boolean hasJavaTimeModule = objectMapper.getRegisteredModules().stream() .anyMatch(module -> module instanceof JavaTimeModule); assertThat(hasJavaTimeModule).isTrue(); }
这种方式不依赖模块ID的返回值,只要模块被正确注册就能通过测试,兼容性更强。
内容的提问来源于stack exchange,提问作者Rohi

