我有两个具有父子关系的类,第二个是第一个的模拟。
public class A {
public void doSomething(){...};
}
public class MockA extends A {
@Override
public void doSomething() {...};
}
我还有两个@Configuration类,一个用于开发环境,一个用于测试,测试一个仅模拟了几种行为,但它导入了开发中的一个。无论哪种方式,我都希望在测试环境中为MockA注入代码,并在开发中为A类注入其他将其自动连接的服务。
如果我在测试配置中覆盖Bean,我可以这样做。以下将起作用:
@Configuration
public class ApplicationConfig {
@Bean
public A beanA() {
return new A();
}
}
@Configuration
public class TestApplicationConfig {
@Bean
public A beanA() {
return new MockA();
}
}
但是,我不想在@Configuration类中创建bean。我想在每个组件上放置@Component批注,然后将它们正确注入服务中。
我尝试了两种方法
1)创建一个虚拟注释,将注释添加到类A上,并尝试从TestApplicationConfig中排除该bean。
@Configuration
@ComponentScan(
basePackages = {
"murex.connectivity.tools.interfaces.monitor.cellcomputer",
"murex.connectivity.tools.interfaces.monitor"
}, excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes =
MyAnnotation.class))
public class TestApplicationConfig {
}
2)在MockA类上使用@Component和@Primary批注。我的逻辑是,在两种情况都存在的情况下(这只会在测试用例中发生,因为只有在扫描MockA之后才会发生这种情况),MockA会被注入到所有地方。但这不会发生。
我想知道我是在做错什么,还是Spring的限制? @Primary批注似乎正是针对此特定情况构造的,我是否误解了?这两个类是否存在父子关系,这是事实吗?
L.E。使用两个不同的配置文件将起作用。如果我对所介绍的两种方法的理解是正确的,并且/或者如果这是对使用@Component注释的Spring的限制,我会感到好奇
答案 0 :(得分:1)
您可以使用配置文件。
@Profile("!test")
@Configuration
public class ApplicationConfig {
@Bean
public A beanA() {
return new A();
}
}
对于测试用例:
在application.properties:spring.profiles.active=test
或测试类@ActiveProfiles("test")
的测试资源中,并创建配置:
@Profile("test")
@Configuration
public class TestApplicationConfig {
@Bean
public A beanA() {
return new MockA();
}
}
答案 1 :(得分:1)
试图结合两种建议的方法。它对我有用:
@Component
@Primary
public class ClassA {
public void doSomething() {
System.out.println("A");
}
}
@Component
public class ClassB extends ClassA {
@Override
public void doSomething() {
System.out.println("B");
}
}
@Component
public class ClassC {
@Autowired
public ClassA component;
}
所有三个类都在同一包中。
@Configuration
@ComponentScan(value = "com.test", excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes =
Primary.class))
public class RandomConfig {
}
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {RandomConfig.class})
public class RandomTest {
@Autowired
ClassC c;
@Test
void when_then() {
//prints "B"
c.component.doSomething();
}
}
因此RandomConfig
排除了所有@Primary
bean,而生产配置仅使用@Primary