有一个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
首先运行测试类是可以的,但是如果在Application类之上添加ComponentScan
注释
@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]
答案 0 :(得分:1)
您面临的问题可能是由于@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
由于在运行测试时实际上并没有提供整个应用程序数据,包括属性值等,因此spring无法为sqlSessionTemplate.java
创建bean,这可能需要一些未在测试中加载的属性值。
可以与 @RunWith(SpringRunner.class)用于典型的MongoDB测试。可以使用 当测试仅针对MongoDB组件时。使用此注释 将禁用完全自动配置,而仅适用 与MongoDB测试相关的配置。默认情况下,带注释的测试 使用@DataMongoTest时将使用嵌入式内存MongoDB进程(如果 可用)。
最好为运行测试定义一个单独的主类,以便您可以在运行测试时完全控制配置。
引用here
答案 1 :(得分:0)
原因:
@SpringBootApplication的基础组件扫描配置定义了排除过滤器,这些过滤器用于确保切片按预期工作。如果在@SpringBootApplication注释的类上使用显式的@ComponentScan指令,请注意这些过滤器将被禁用。如果使用切片,则应重新定义它们。
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html
解决:
@ComponentScan(value="com.foo",excludeFilters = { @ComponentScan.Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class) })
如果直接使用@ComponentScan(即,不是通过@SpringBootApplication),则需要向其中注册TypeExcludeFilter。有关详细信息,请参见Javadoc。
CompanyRecommendationDaoTest
)相同的包中定义了单独的主类 @SpringBootApplication
public class DaoTestApplication {
public static void main(String[] args) {
SpringApplication.run(DaoTestApplication.class, args);
}
}