You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置或Mock Vert.x JsonObject.mapFrom解决LocalDateTime序列化问题

Vert.x JsonObject.mapFrom LocalDateTime序列化问题解决方案

问题场景

测试过程中抛出序列化异常:
java.lang.IllegalArgumentException: Java 8 date/time type java.time.LocalDateTime not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling
已知约束:

  • 已引入jackson-datatype-jsr310依赖,自定义ObjectMapper中已注册JavaTimeModule,自定义序列化逻辑运行正常
  • 业务代码通过io.vertx.core.json.JsonObject.mapFrom()完成Java对象到JSON的转换,该方法未使用自定义配置的ObjectMapper,持续抛出上述LocalDateTime序列化错误
  • 测试阶段无权修改主业务代码:既不能替换原有mapFrom调用逻辑,也不能在实体类添加序列化注解,常规方式无法直接MockJsonObject.mapFrom静态方法
    涉及业务代码片段:
// Class1类中的被测方法
public void getSomething(Request request){
    JsonObject jsonObject = JsonObject.mapFrom(helper);
    // 后续jsonObject相关业务逻辑
}
// 包含LocalDateTime字段的Helper类
public class Helper {
    LocalDateTime createdAt = LocalDateTime.now();
    // 该字段触发序列化报错
}

问题答复

1. 是否可通过ObjectMapper配置修改JsonObject.mapFrom方法的默认序列化行为?

可以,无需修改任何业务代码。
JsonObject.mapFrom()底层默认使用Vert.x框架自身持有的全局静态ObjectMapper实例,不会感知业务代码中自定义构造的ObjectMapper配置。你只需要在测试启动阶段(比如测试类的@BeforeAll初始化节点),直接修改Vert.x全局持有的这个ObjectMapper实例,注册对应序列化模块即可。
实现代码:

import io.vertx.core.json.Json;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.junit.jupiter.api.BeforeAll;

@BeforeAll
public static void initVertxJsonConfig() {
    // 拿到Vert.x内部默认使用的全局ObjectMapper
    ObjectMapper defaultMapper = Json.mapper;
    // 注册JavaTimeModule支持Java8时间类型序列化
    defaultMapper.registerModule(new JavaTimeModule());
    // 按需配置:关闭时间戳格式,按ISO字符串格式输出时间
    defaultMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
}

说明:这个全局Mapper是Vert.x官方开放给用户做配置扩展的入口,配置完成后所有调用JsonObject.mapFrom/Json.encode等Vert.x自带JSON序列化方法的逻辑都会使用该配置,不存在侵入业务代码的问题,只需要保证配置在mapFrom方法被调用前执行即可。


2. 是否有可行方案可Mock该静态方法,无需修改业务代码即可完成测试?

可以,使用支持静态方法Mock的测试工具即可,无需改动业务代码。
目前Mockito 3.4.0及以上版本原生支持静态方法Mock,不需要引入PowerMock等额外组件,实现方式如下:

import org.mockito.MockedStatic;
import org.mockito.Mockito;
import static org.mockito.ArgumentMatchers.any;
import org.junit.jupiter.api.Test;

@Test
void testGetSomethingLogic() {
    // 提前构造测试数据和预期返回的JSON对象
    Request testRequest = new Request();
    JsonObject mockJson = new JsonObject()
            .put("createdAt", "2024-05-20T14:30:00");

    // 开启JsonObject类的静态Mock,try-with-resources块执行完后会自动关闭Mock,避免污染其他测试用例
    try (MockedStatic<JsonObject> jsonObjectMock = Mockito.mockStatic(JsonObject.class)) {
        // 桩逻辑:当传入Helper类型参数调用mapFrom时,返回提前构造好的mockJson
        jsonObjectMock.when(() -> JsonObject.mapFrom(any(Helper.class)))
                .thenReturn(mockJson);

        // 执行被测方法
        class1.getSomething(testRequest);

        // 后续执行你的断言逻辑,验证业务行为是否符合预期
        // ...
    }
}

注意:静态Mock的作用域必须控制在单个测试用例范围内,不要全局开启,避免影响其他测试用例的正常执行。如果使用低于3.4.0版本的Mockito,也可以通过PowerMock实现同等的静态方法Mock效果,配置逻辑类似。


内容的提问来源于stack exchange,提问作者ss13199

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 23:42:27