Spring Boot用@JsonTest测试DTO序列化时触发Mongo Repository创建失败
这是个很常见的Spring Boot切片测试坑——你用@JsonTest本来是想专注测试DTO的JSON序列化,结果Spring却非要去创建MongoDB的Repository Bean,导致启动失败。本质原因是@JsonTest会默认继承主应用类的组件扫描和自动配置,如果你的主应用类(带@SpringBootApplication的那个)的扫描范围包含了Repository所在的包,测试上下文就会尝试实例化这些Repository,但测试环境里要么没配置MongoDB,要么根本不需要这些Bean。
给你几个实用的解决办法:
方法一:精准控制测试的组件扫描范围
在测试类上加上@ComponentScan,只指定DTO所在的包,让Spring只加载需要的类:@JsonTest @RunWith(SpringRunner.class) @ComponentScan(basePackages = "com.yourproject.dto") // 替换成你实际的DTO包路径 public class SomeDTOTest { @Autowired JacksonTester<SomeDTO> json; @Test public void someTest() { // 你的测试逻辑 } }或者直接排除Repository相关的组件:
@JsonTest @RunWith(SpringRunner.class) @ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Repository.class)) public class SomeDTOTest { // ... }方法二:排除MongoDB的自动配置类
直接告诉Spring不要加载MongoDB相关的自动配置,从根源上阻止Repository Bean的创建:@JsonTest @RunWith(SpringRunner.class) @EnableAutoConfiguration(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class}) public class SomeDTOTest { // ... }如果你的项目里还有其他测试数据库的配置,也可以加上
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)来禁用测试数据库的自动配置。方法三:调整测试类的包结构
把测试类放在和主应用Repository不同的包层级下,比如主应用Repository在com.yourproject.repository,测试类放在com.yourproject.dto.test,这样Spring默认的组件扫描就不会扫到Repository了。不过这个方法依赖项目结构,灵活性不如前两个。
另外提一句,别想着用@MockBean去Mock Repository——完全没必要,@JsonTest的核心就是只加载JSON处理相关的组件,直接排除掉不需要的配置才是正确的思路。
内容的提问来源于stack exchange,提问作者Tomasz Bawor

