spring-boot - 为什么 @ComponentScan 然后 DataMongoTest 不起作用
问题描述
有一个 mongo dao 类com.foo.bar.dao.CompanyRecommendationDao
,也有一个对应的测试类:com.foo.bar.dao.CompanyRecommendationDaoTest
.
@RunWith(SpringRunner.class)
@DataMongoTest(includeFilters = @ComponentScan.Filter(type= FilterType.ASSIGNABLE_TYPE,value={CompanyRecommendationDao.class}))
@Import(SpringMongoConfig.class)
public class CompanyRecommendationDaoTest
第一次运行测试类是可以的,但是如果ComponentScan
在Application类上面添加注释
@SpringBootApplication
@ComponentScan("com.foo")
public class BarApplication
在这种情况下,运行 CompanyRecommendationDaoTest 可能会出现以下错误
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'companyManagementService': Unsatisfied dependency expressed through field 'companyMapper'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'companyMapper' defined in file [/Users/zhugw/develop/workspace/bar/target/classes/com/foo/bar/mapper/CompanyMapper.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
那么为什么它可以加载其他服务类,它应该只加载 mongo 相关类?
来自DataMongoTest
javadoc
当测试只关注 MongoDB 组件时可以使用。使用此注解将禁用完全自动配置,而是仅应用与 MongoDB 测试相关的配置。
如果显式添加 @ComponentScan("com.foo") 有什么区别(默认包是 com.foo.bar)?
PS。启用跟踪日志时
情况1(没有@ComponnetScan)
2019-06-02 22:28:08.876 TRACE 13875 --- [ main] o.s.c.a.ClassPathBeanDefinitionScanner : Scanning file [/Users/zhugw/develop/workspace/foo/bar/target/classes/com/foo/bar/dao/CompanyRecommendationDao.class]
2019-06-02 22:28:08.877 TRACE 13875 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'org.springframework.boot.test.context.filter.TestTypeExcludeFilter'
2019-06-02 22:28:08.877 TRACE 13875 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'org.springframework.boot.test.autoconfigure.filter.TypeExcludeFilters'
2019-06-02 22:28:08.877 DEBUG 13875 --- [ main] o.s.c.a.ClassPathBeanDefinitionScanner : Identified candidate component class: file [/Users/zhugw/develop/workspace/foo/bar/target/classes/com/foo/bar/dao/CompanyRecommendationDao.class]
情况2(使用@ComponnetScan)
2019-06-02 22:40:23.989 TRACE 14573 --- [ main] o.s.c.a.ClassPathBeanDefinitionScanner : Scanning file [/Users/zhugw/develop/workspace/foo/bar/target/classes/com/foo/bar/dao/CompanyRecommendationDao.class]
2019-06-02 22:40:23.989 DEBUG 14573 --- [ main] o.s.c.a.ClassPathBeanDefinitionScanner : Identified candidate component class: file [/Users/zhugw/develop/workspace/foo/bar/target/classes/com/foo/bar/dao/CompanyRecommendationDao.class]
解决方案
您面临的问题可能是由于@ComponentScan
. 最初,当您使用@DataMongotTest
注解时,spring 仅配置运行 mongo 所必需的 bean。但是当您将组件扫描注解添加到主类并设置包扫描级别时, "com.foo"
spring 将自动搜索并查找所有注册的 bean此路径下的软件包。
Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
由于您在运行 test 时实际上并未提供包括属性值等在内的整个应用程序数据,因此 spring 无法为 bean 创建 bean sqlSessionTemplate.java
,这可能需要一些未在 test 中加载的属性值。
可以与 @RunWith(SpringRunner.class) 结合使用的注释,用于典型的 MongoDB 测试。当测试只关注 MongoDB 组件时可以使用。使用此注解将禁用完全自动配置,而是仅应用与 MongoDB 测试相关的配置。默认情况下,使用 @DataMongoTest 注释的测试将使用嵌入式内存中的 MongoDB 进程(如果可用)。
为运行测试定义一个单独的主类是一种很好的做法,这样您就可以在运行测试时完全控制配置。
参考这里
推荐阅读
- css - 在 CSS 中选择最内部的等效规则
- java - 如何根据比较连续的列表元素将 Java 流减少为布尔值
- javascript - gif动画只有在包含slick.js幻灯片后才能启动吗?
- python - Python中的嵌套字典并更新键中的特定键
- typescript - 如何将变压器传递给 ts-node?
- javascript - JavaScript,如何在下一行继续表达
- sql - 将行转置为 postgres 中的列
- python - 了解 train_test_split 方法
- go - 使用 google.protobuf.Timestamp 在 Go 中解析具有时区偏移的日期时间戳
- python - 我有一串xml要发布到具有多个元素但只发布第一个元素然后停止的API