spring scanner为所有测试拾取了带有@Configuration的内部静态类。怎么了?
Spring从Test2中获取Test1的内部spring scanner为所有测试拾取了带有@Configuration的内部静态类。怎么了?,spring,spring-boot,junit,Spring,Spring Boot,Junit,Spring从Test2中获取Test1的内部@Configuration。在Test2中我需要一个模拟的IService,但在Test1中需要一个真正的serviceinpl。此外,我还希望为所有测试提供公共TestConfiguration。但在两次测试中,我总是嘲笑iSeries。怎么了 如何禁用兄弟测试的内部配置拾取 这是我的密码: ServiceImpl.java: @Service public class SeriviveImpl implements IService { }
@Configuration
。在Test2中我需要一个模拟的IService
,但在Test1中需要一个真正的serviceinpl
。此外,我还希望为所有测试提供公共TestConfiguration
。但在两次测试中,我总是嘲笑iSeries。怎么了
如何禁用兄弟测试的内部配置拾取
这是我的密码:
ServiceImpl.java:
@Service
public class SeriviveImpl implements IService {
}
TestConfiguration.java:
@Configuration
@ComponentScan
public class TestConfiguration {
// empty
}
Test1.java:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestConfiguration.class})
public class Test1 {
@Autowired
private IService service;
}
Test2.java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {Test2.CustomConfiguration.class, TestConfiguration.class})
public class Test2 {
@Autowired
private IService service;
@Configuration
static class CustomConfiguration {
@Bean
IService service() {
return mock(IService.class);
}
}
}
您可以通过使用
org.springframework.beans.factory.annotation.Qualifier
annotation显式选择所需的实现来实现这一点。下面是您的代码可能的样子:
...
@Service
@Qualifier("impl")
public class SeriviveImpl implements IService {}
...
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestConfiguration.class})
public class Test1 {
@Autowired
@Qualifier("impl")
private IService service;
}
...
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {Test2.CustomConfiguration.class,TestConfiguration.class})
public class Test2 {
@Autowired
@Qualifer("mock")
private IService service;
@Configuration
static class CustomConfiguration {
@Bean
@Qualifier("mock")
IService service() { return mock(IService.class); }
}
}
您可以从TestConfiguration@ComponentScan筛选内部类:
@Configuration
@ComponentScan(excludeFilters = {
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,
value = Test2.CustomConfiguration.class)
})
public class TestConfiguration {
// empty
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Configuration
public @interface InnerConfiguration {
}
这将防止它在Test1中被拾取
编辑或者,如果您有很多内部配置,您可以创建自己的注释,并从@ComponentScan中筛选所有这些注释类:
@Configuration
@ComponentScan(excludeFilters = {
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,
value = Test2.CustomConfiguration.class)
})
public class TestConfiguration {
// empty
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Configuration
public @interface InnerConfiguration {
}
然后在内部类上使用此注释,而不是@Configuration:
@InnerConfiguration
static class CustomConfiguration {
@Bean
IService service() {
return mock(IService.class);
}
}
并从组件扫描中过滤这些内容,如下所示:
@Configuration
@ComponentScan(excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,
value = InnerConfiguration.class)
})
public class TestConfiguration {
// empty
}
由于在
Test2
的@ContextConfiguration
注释中显式使用Test2.CustomConfiguration.class
,因此可以从Test2.CustomConfiguration
中删除@Configuration
注释,并且在Test1
运行期间,@ComponentScan
不会拾取该注释
这是因为:
使用带注释的
类(请参见基于Java的容器配置),您可以对
使用@ContextConfiguration测试类并配置这些类
属性,该属性的数组包含对注释类的引用
及
术语“注释类”可以指任何
以下:
用@Configuration注释的类
组件(即,用@component、@Service、,
@存储库或其他原型注释)
一个JSR-330兼容类,用javax.inject注释
注释
包含@Bean方法的任何其他类。
看我想一定还有别的办法。将@Qualifier添加到实现中,因为测试配置相交不是我的方式。是的,我可以,但TestConfiguration现在对Test2的了解是不好的。TestConfiguration理想情况下不应该知道本地子配置。它知道,因为您正在扫描组件,@Configuration是一个组件。这就是春天的工作原理。如果你不想让它把它捡起来,那么你必须过滤掉它。我很确定这是你最好的选择。但是如果我有20多个自定义配置的测试?我需要在公共配置中定义所有这些。这不是很难看吗?编辑我的答案,当你有很多自定义配置谢谢,这是最好的解决方案!