Spring Boot JpaRepository测试启动失败:找不到InitService Bean
问题解决:测试JpaRepository时找不到InitService Bean
报错原因
使用@DataJpaTest测试Repository时,Spring Boot会创建一个仅包含JPA相关组件的精简上下文(比如Repository、EntityManager、DataSource等)。但你的主应用类SocializerApplication被自动扫描到,而主类中@Autowired的InitService不在这个精简上下文的组件范围内,导致启动失败。
解决方法
方案一:模拟缺失的Bean(推荐)
在测试类上添加@MockBean注解,模拟InitService,让Spring上下文能正常初始化,同时不影响Repository的测试:
@DataJpaTest @MockBean(com.project.socializer.runner.InitService.class) // 模拟InitService class UserRepositoryTest { @Autowired UserRepository userRepository; @BeforeEach void setUp() { userRepository.save(new UserEntity("Jhon","Doe","jhon.doe@gmail.com","test1234","1999-12-19",new Roles("USER"))); } @AfterEach void afterEach() { userRepository.deleteAll(); } @Test void findByEmail() { Optional<UserEntity> userTest = userRepository.findByEmail("jhon.doe@gmail.com"); assertTrue(userTest.isPresent(),"User Exist"); } }
方案二:调整主应用类的依赖配置
如果InitService是用于启动初始化数据的工具类,可以给它添加条件注解,让它仅在生产/非测试环境加载:
// 给InitService类添加条件注解 @Component @ConditionalOnProperty(name = "spring.profiles.active", notHavingValue = "test") public class InitService { // 原有业务代码 }
或者将主类中对InitService的注入改为可选:
// 在SocializerApplication类中修改Autowired注解 @Autowired(required = false) private InitService initService;
方案三:加载完整Spring上下文(不推荐)
如果确实需要在测试中加载完整应用上下文,可替换@DataJpaTest为@SpringBootTest,并指定使用H2数据库:
@SpringBootTest @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.ANY) class UserRepositoryTest { // 原有代码不变 }
注意:此方案会加载完整应用上下文,测试启动速度较慢,仅在必要时使用。
额外优化
你的测试类中存在冗余注解:@ExtendWith(MockitoExtension.class)和@ExtendWith(SpringExtension.class),在Spring Boot 2.2及以上版本中,@DataJpaTest已自动集成这些扩展,可直接删除。
内容的提问来源于stack exchange,提问作者Don Fleym
相关产品推荐
相关产品推荐

