在编写 Spring 集成测试时从 Spring 组件扫描中排除特定类 [英] Exclude a particular class from Spring Component scan while writing Spring Integration Test

查看:34
本文介绍了在编写 Spring 集成测试时从 Spring 组件扫描中排除特定类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的课程是..

位于 src/intregation-test/java

lies in src/intregation-test/java

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = StoreOrderFulfillmentApplication.class)
  @ActiveProfiles("Test")
  public class OrderCreationIntregationTest {

@Autowired
private TestRestTemplate restTemplate;

@MockBean
private OrderRepository orderRepository;

@MockBean
private OrderLineItemRepository orderLineItemRepository;

@MockBean
private InternalEventPublisher internalEventPublisher;

@SuppressWarnings("unchecked")
@Before
public void setup() {
    Mockito.when(orderRepository.findByOfsReferenceId("OFS:GMO:Z100002062-99")).thenReturn(null);
    OrderEntity savedOrder = new OrderEntity();
    savedOrder.setOrderId(1023);
    Mockito.when(orderRepository.save(Mockito.any(OrderEntity.class))).thenReturn(savedOrder);
    Iterable<OrderLineItemEntity> orderLineItemList = prepareOrderLineItemEntityIterable();
    Mockito.when(orderLineItemRepository.save(Mockito.any(Iterable.class))).thenReturn(orderLineItemList);
}

@Test
public void test() throws ParseException {
    FulfillmentOrder fulfillmentOrderRequestVO = new FulfillmentOrder();
    fulfillmentOrderRequestVO = buildFulfillmentOrder();
    String myMessage = "Order Created";
    ResponseEntity<ResponseOrderMessage> responseEntity = restTemplate.postForEntity("/fulfillmentprocessor/orders",
            fulfillmentOrderRequestVO, ResponseOrderMessage.class);
    ResponseOrderMessage responseOrderMessage = responseEntity.getBody();
    assertEquals(HttpStatus.CREATED, responseEntity.getStatusCode());
    assertEquals(myMessage, responseOrderMessage.getMessage());
}

位于 src/main/java

lies in src/main/java

@SpringBootApplication
public class StoreOrderFulfillmentApplication {

public static void main(String[] args) {
    SpringApplication.run(StoreOrderFulfillmentApplication.class, args);
}
}

现在的问题是我想排除一个类从获取组件扫描.我这个类包含对 apache Kafka 的依赖.如果这个类在容器启动时加载,它就会开始寻找 kafka 运行实例.所以在运行整合测试时,我不会启动我的 Kafka 服务器,所以我想运行集成测试使 kafka 关闭.

Now the problem is I wanted to exclude a class from being get component scanned.my this class contains the dependency for apache Kafka. if this class loads while container start up it start looking for kafka running instances. so while running Intregation test I will not be starting my Kafka server,so I wanted to run Intregation test making kafka shutdown.

这个我可以通过在 StoreOrderFulfillmentApplication 类中添加一行代码来实现

This I can achieved by adding one line code in StoreOrderFulfillmentApplication class

@ComponentScan(basePackages = "com.tesco.store.order.fulfillment.processor", excludeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = OrderReceiveEventConfiguration.class))

通过添加这行代码 StoreOrderFulfillmentApplication 类,它从获取组件扫描中排除 OrderReceiveEventConfiguration 类.

by addding this line of code StoreOrderFulfillmentApplication class it is excluding OrderReceiveEventConfiguration class from being get component scanned.

现在的问题是我不认为在主代码中添加任何测试配置更改.所以我正在努力从 src/intregation-test/java 源文件夹中做同样的排除,这是我可以在容器启动代码期间排除这个特定类的某种方式.

now the problem is I not suppose add any test configuration changes in the main code. so I am struggling to do the same exclusion from src/intregation-test/java source folder, is their some way that I can exclude this particular class during container startup code.

但它不应该影响我的主类代码意味着src/main/java

but it should not affect my main class code means code inside src/main/java

感谢任何帮助..

推荐答案

您可以使用 @Conditional 如下所示.

You can make use of @Conditional as shown below.

  • application.properties 中引入一个属性,比如kafka.enabled.
  • 使用 @Conditional(PropertyCondition.class)
  • 注释 OrderReceiveEventConfiguration
  • 取决于 kafka.enabled 值即.true(正常运行)或 false(测试)OrderReceiveEventConfiguration在不更改代码的情况下分别被拾取或忽略.
  • In application.properties introduce a property say kafka.enabled.
  • Annotate the OrderReceiveEventConfiguration with @Conditional(PropertyCondition.class)
  • Depending on kafka.enabled value viz. true (for normal run) or false (for testing) the OrderReceiveEventConfiguration will be picked up or ignored respectively without changing the code.

如果需要更多信息,请在评论中告知.

Let know in comments in case any more information is required.

除了主要的@conditional注解,还有一组类似的注解用于不同的情况.

Except main @conditional annotation there are set of similar annotation to be used for different cases.

@ConditionalOnClass@ConditionalOnMissingClass 注释允许根据特定类的存在或不存在来包含配置.

The @ConditionalOnClass and @ConditionalOnMissingClass annotations allows configuration to be included based on the presence or absence of specific classes.

例如当 OObjectDatabaseTx.class 被添加到依赖项并且没有 OrientWebConfigurer bean 时,我们创建了配置器.

E.g. when OObjectDatabaseTx.class is added to dependencies and there is no OrientWebConfigurer bean we create the configurer.

@Bean
@ConditionalOnWebApplication
@ConditionalOnClass(OObjectDatabaseTx.class)
@ConditionalOnMissingBean(OrientWebConfigurer.class)
public OrientWebConfigurer orientWebConfigurer() {
    return new OrientWebConfigurer();
}

Bean 条件

@ConditionalOnBean@ConditionalOnMissingBean 注释允许根据特定 bean 的存在或不存在来包含 bean.您可以使用 value 属性按类型指定 bean,或使用 name 属性按名称指定 bean.search 属性允许您限制搜索 bean 时应考虑的 ApplicationContext 层次结构.

Bean conditions

The @ConditionalOnBean and @ConditionalOnMissingBean annotations allow a bean to be included based on the presence or absence of specific beans. You can use the value attribute to specify beans by type, or name to specify beans by name. The search attribute allows you to limit the ApplicationContext hierarchy that should be considered when searching for beans.

当我们检查是否没有定义的bean时,参见上面的例子.

See the example above when we check whether there is no defined bean.

@ConditionalOnProperty 注释允许基于 Spring Environment 属性包含配置.使用 prefix 和 name 属性来指定应该检查的属性.默认情况下,将匹配任何存在且不等于 false 的属性.您还可以使用 sharingValuematchIfMissing 属性创建更高级的检查.

The @ConditionalOnProperty annotation allows configuration to be included based on a Spring Environment property. Use the prefix and name attributes to specify the property that should be checked. By default any property that exists and is not equal to false will be matched. You can also create more advanced checks using the havingValue and matchIfMissing attributes.

@ConditionalOnProperty(value='somebean.enabled', matchIfMissing = true, havingValue="yes")
@Bean 
public SomeBean someBean(){
}

资源条件

@ConditionalOnResource 注释允许仅在存在特定资源时才包含配置.

Resource conditions

The @ConditionalOnResource annotation allows configuration to be included only when a specific resource is present.

@ConditionalOnResource(resources = "classpath:init-db.sql") 

网络申请条件

@ConditionalOnWebApplication@ConditionalOnNotWebApplication 注释允许根据应用程序是否为网络应用程序"来包含配置.

Web application conditions

The @ConditionalOnWebApplication and @ConditionalOnNotWebApplication annotations allow configuration to be included depending on whether the application is a 'web application'.

@Configuration
@ConditionalOnWebApplication
public class MyWebMvcAutoConfiguration {...}

SpEL 表达条件

@ConditionalOnExpression 注释允许根据 SpEL 表达式的结果包含配置.

SpEL expression conditions

The @ConditionalOnExpression annotation allows configuration to be included based on the result of a SpEL expression.

@ConditionalOnExpression("${rest.security.enabled}==false")

这篇关于在编写 Spring 集成测试时从 Spring 组件扫描中排除特定类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆