集成测试返回Page<MyDto>遇InvalidDefinitionException的替代方案
解决Spring Data Page反序列化集成测试问题的替代方案
你遇到的是Jackson无法反序列化抽象类Page的问题——因为它没有默认构造器,也未指定具体实现类。除了包装PageImpl,还有几个简单可行的方案:
1. 配置Jackson将Page映射到PageImpl
在测试专属的配置类中添加Jackson类型映射规则,让Jackson明确遇到抽象Page时,用具体的PageImpl来实例化:
方式一:通过Jackson2ObjectMapperBuilder添加Mixin
@Configuration @Profile("test") public class TestJacksonConfig { @Bean public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() { return new Jackson2ObjectMapperBuilder() .mixIn(Page.class, PageImplMixin.class); } // 定义Mixin类,提供PageImpl的构造器签名供Jackson识别 abstract static class PageImplMixin<T> extends PageImpl<T> { protected PageImplMixin(List<T> content, Pageable pageable, long total) { super(content, pageable, total); } } }
方式二:注册Jackson模块指定抽象类型映射
@Configuration @Profile("test") public class TestJacksonConfig { @Bean public Module pageDeserializationModule() { SimpleModule module = new SimpleModule(); // 告诉Jackson,Page抽象类的具体实现为PageImpl module.addAbstractTypeMapping(Page.class, PageImpl.class); return module; } }
这两种方式都不需要额外创建包装类,且通过@Profile("test")限定只在测试环境生效,不会影响生产代码。
2. 在测试用Feign客户端中指定返回PageImpl
如果是Feign调用导致的解码错误,可以直接在测试环境的Feign接口中,把返回类型从抽象的Page<MyDto>改成具体的PageImpl<MyDto>:
@FeignClient(name = "my-service") @Profile("test") public interface TestMyFeignClient { @GetMapping("/items") PageImpl<MyDto> getItems(Pageable pageable); }
生产环境依然使用返回Page<MyDto>的原接口,互不干扰。
3. 测试中手动指定反序列化类型
如果是自己手动处理响应体的反序列化,可以在测试代码中给ObjectMapper明确指定具体类型:
// 获取接口响应体 String responseBody = mockMvc.perform(get("/items")) .andReturn() .getResponse() .getContentAsString(); // 构造指定PageImpl的JavaType ObjectMapper mapper = new ObjectMapper(); JavaType pageType = mapper.getTypeFactory() .constructParametricType(PageImpl.class, MyDto.class); // 反序列化得到Page对象 Page<MyDto> page = mapper.readValue(responseBody, pageType);
内容的提问来源于stack exchange,提问作者user3052078
相关产品推荐
相关产品推荐

