使用 @DataJpaTest 的 Spring 测试无法使用 @Repository 自动装配类(但使用接口存储库可以工作!)
Posted
技术标签:
【中文标题】使用 @DataJpaTest 的 Spring 测试无法使用 @Repository 自动装配类(但使用接口存储库可以工作!)【英文标题】:Spring test with @DataJpaTest can't autowire class with @Repository (but with interface repository works!) 【发布时间】:2018-06-29 01:09:17 【问题描述】:我试图了解为什么我不能自动装配类存储库,但我可以为相同的测试自动装配相同包中的接口存储库。当我启动应用程序时,相同的存储库按预期工作。
首先,错误:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.app.person.repository.PersonRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: @org.springframework.beans.factory.annotation.Autowired(required=true)
at org.springframework.beans.factory.support.DefaultPersonbleBeanFactory.raiseNoMatchingBeanFound(DefaultPersonbleBeanFactory.java:1493)
at org.springframework.beans.factory.support.DefaultPersonbleBeanFactory.doResolveDependency(DefaultPersonbleBeanFactory.java:1104)
at org.springframework.beans.factory.support.DefaultPersonbleBeanFactory.resolveDependency(DefaultPersonbleBeanFactory.java:1066)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 28 more
我有一个非常简单的例子。测试:
@RunWith(SpringRunner.class)
@DataJpaTest
public class PersonRepositoryTest
@Autowired
private PersonRepository personRepository; // fail...
@Autowired
private PersonCrudRepository personCrudRepository; // works!
@Test
public void findOne()
存储库类:
@Repository
public class PersonRepository
//code
仓库界面:
@Repository
public interface PersonCrudRepository extends CrudRepository<Person, Long>
在bad experience with this same error 之后,我试图在我的配置中找到一些细节或测试导致此问题的原因。另一种可能性是@DataJpaTest
不支持类存储库。
【问题讨论】:
BTW 没有必要在你的界面中声明 Repository 注释。 Spring Data 创建的代理在幕后添加了一个,甚至是 Transactional 【参考方案1】:我认为我对这个问题的看法是正确的。找到post on Github后阅读Spring Documentation:
如果您想测试 JPA 应用程序,可以使用@DataJpaTest。经过 默认它会配置一个内存嵌入式数据库,扫描 @Entity 类并配置 Spring Data JPA 存储库。常规的 @Component beans 不会被加载到 ApplicationContext 中。
我的PersonRepository
被认为是常规的@Component
,因为它不是 Spring Data JPA 存储库(接口是)。所以,它没有加载。
替代解决方案是使用@SpringBootTest
而不是@DataJpaTest
。
此解决方案的缺点是会在运行测试时加载所有您的上下文,并因此禁用测试切片。但是做这项工作。
仍然使用@DataJpaTest
的另一个选项是包含@Repository
过滤器注释,如下所示:
@DataJpaTest(includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Repository.class))
【讨论】:
嗨,我尝试了你的解决方案,但我仍然有同样的例外:***.com/questions/62313098/… 顺便说一句 - 关于“这个解决方案的缺点是会加载你所有的上下文”,你可以使用SpringBootTest
和 WebEnvironment.MOCK
来测试只有服务器端(与 Web 无关)。它当然会以某种方式降低性能的影响。【参考方案2】:
另一种选择可能是@Import
,如此处所示https://***.com/a/41084739/384674。
【讨论】:
是的,我认为这是解决方案 这为我解决了同样的问题以上是关于使用 @DataJpaTest 的 Spring 测试无法使用 @Repository 自动装配类(但使用接口存储库可以工作!)的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot:使用 @DataJpaTest 和 Flyway 设置 Hibernate 命名策略
Spring Boot 1.4 @DataJpaTest - 创建名为“dataSource”的 bean 时出错
@DataJpaTest 不会读取 spring.jpa.* 属性,而 @SpringBootTest 会
如何在使用 DataJpaTest 的 Spring Boot 2.0 测试中访问 H2 控制台
使用 @DataJpaTest 的 Spring 测试无法使用 @Repository 自动装配类(但使用接口存储库可以工作!)