Spring从Test2中为Test1选取内部@Configuration
。我需要在Test2中使用模拟的IService
,但在Test1中需要一个真实的ServiceImpl
。此外,我希望我的所有测试都有共同的TestConfiguration
。但我总是在两个测试中都嘲笑IService。怎么了?
如何禁用内部配置以获取兄弟测试?
这是我的代码:
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);
}
}
}
答案 0 :(得分:2)
您可以从TestConfiguration @ComponentScan中过滤内部类:
@Configuration
@ComponentScan(excludeFilters = {
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,
value = Test2.CustomConfiguration.class)
})
public class TestConfiguration {
// empty
}
这将阻止它在Test1中被拾取。
编辑或者,如果您有许多内部配置,您可以创建自己的注释并从@ComponentScan中过滤所有这些带注释的类:
@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
}
答案 1 :(得分:0)
您可以通过使用org.springframework.beans.factory.annotation.Qualifier
注释明确选择所需的实现来实现这一点。以下是您的代码的外观:
...
@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); }
}
}
答案 2 :(得分:0)
由于您在Test2.CustomConfiguration.class
的{{1}}注释中明确使用了Test2
,因此可以从@ContextConfiguration
删除@Configuration
注释,并且该注释不会被Test2.CustomConfiguration
运行期间@ComponentScan
。
之所以有效,是因为:
使用带注释的方法为测试加载ApplicationContext 类(请参阅基于Java的容器配置),您可以进行注释 @ContextConfiguration测试类并配置这些类 属性,该数组包含对带注释的类的引用。
和
“带注释的类”一词可以指任何 以下:
用@Configuration注释的类。
一个组件(即带有@ Component,@ Service, @Repository或其他构造型注释)。
一个与JSR-330兼容的类,并用javax.inject注释 注释。
任何其他包含@Bean方法的类。