如何为带@JsonSubTypes注解的Java多态类创建FullScan类型测试对象
解决方案
问题核心原因
你当前的写法存在两个问题:
@NoArgsConstructor生成的无参构造不会初始化@NonNull修饰的type字段,直接实例化会导致字段为空,不符合校验规则- 你通过
@JsonSubTypes配置了多态映射,type="FullScan"对应的实际实现类是FullScan子类,直接实例化父类BatchSpec不符合JSON反序列化后的真实对象类型
可用实现方案
按推荐优先级排序:
方案1:直接实例化对应子类(最推荐)
Jackson反序列化时遇到type="FullScan"会自动返回FullScan类实例,该类本身是BatchSpec的子类,完全符合类型要求:
// 直接实例化子类即可,若FullScan类加了@Data,可主动设置type确保符合要求 private static final BatchSpec batchSpec = new FullScan(); // 若需要手动赋值type,可通过静态代码块设置 static { batchSpec.setType("FullScan"); }
你也可以在FullScan类的无参构造中默认给type赋值,避免每次手动设置:
@Data @NoArgsConstructor public class FullScan extends BatchSpec { public FullScan() { this.setType("FullScan"); } // 其他业务字段 }
方案2:通过ObjectMapper模拟反序列化(和真实运行逻辑完全一致)
如果希望测试对象和实际业务中JSON反序列化生成的对象完全一致,直接用Jackson的ObjectMapper读JSON生成即可:
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); private static final BatchSpec batchSpec; static { try { batchSpec = OBJECT_MAPPER.readValue("{\"type\": \"FullScan\"}", BatchSpec.class); } catch (JsonProcessingException e) { throw new RuntimeException("测试BatchSpec对象初始化失败", e); } }
方案3:直接实例化父类后设值(不推荐)
如果临时需要构造父类对象,可通过@Data生成的setter赋值type字段:
private static final BatchSpec batchSpec = new BatchSpec(); static { batchSpec.setType("FullScan"); }
注意:该方式生成的是父类实例,和实际反序列化得到的子类实例类型不同,可能导致多态相关的测试逻辑失效。
内容的提问来源于stack exchange,提问作者Shiv
相关产品推荐
相关产品推荐

