首页 > 解决方案 > AnnotationConfigApplicationContext 构造函数无法在集成测试中处理@Value 的注入

问题描述

我正在尝试编写一个调用弹簧组件的主要方法的集成测试。类如下所示。

@Component
@PropertySources(value = { @PropertySource("classpath:detection.properties") })
public class DetectionApp {

  public void execute() {
    try {

      LOGGER.info("Detection App exiting");
      System.exit(0);
    } catch (RuntimeException re) {
      LOGGER.error("Error occurred queuing failed org ids", re);
      System.exit(RUNTIME_EXCEPTION_ERROR);
    }
  }

  public static void main(final String[] args) {
    final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TrackingServiceClientConfig.class);
    context.scan(COMPONENT_PACKAGE);
    final DetectionApp app = context.getBean(DetectionApp.class);
    app.execute();
  }

配置类:

@Configuration
public class TrackingServiceClientConfig {

  TrackingServiceClient.Builder getTrackingServiceClientBuilder() {
    return TrackingServiceClient.builder();
  }

  @Bean
  public Client getClient() {
    return new OkHttpClient();
  }

  @Bean
  public TrackingServiceClient trackingServiceClient(
    @Value("${tracking.base.url}") String url,
    @Value("${tracking.connectTimeout}") int connectTimeout,
    @Value("${tracking.readTimeout}") int readTimeout,
    @Value("${tracking.max_retries}") int maxRetries,
    @Value("${tracking.retry_interval}") long retryInterval,
    Client client,
    Gson gson
  ) {

    return getTrackingServiceClientBuilder()
             .withBaseUrl(url)
             .withClient(client)
             .withConnectTimeout(connectTimeout)
             .withReadTimeout(readTimeout)
             .build();
  }

}

这是我的测试课:

@ExtendWith(SpringExtension.class)
@SpringBootTest
@EnableAutoConfiguration(exclude = { ContextRegionProviderAutoConfiguration.class, DataSourceAutoConfiguration.class,
  DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class, JdbcRepositoriesAutoConfiguration.class })
@ComponentScan(basePackages = { "com.notification.configuration" },
  excludeFilters = { @ComponentScan.Filter(type = FilterType.ANNOTATION, value = SpringBootApplication.class),
    @ComponentScan.Filter(type = FilterType.REGEX, pattern = ".*DetectionApp.*"),
    @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = SpringDataConfiguration.class)})
@ContextConfiguration
public class DetectionAppIT {

  @MockBean
  SynchronizationService synchronizationService;

  @MockBean
  OrgQueueSender orgQueueSender;

  @Test
  void testMainMethod() {
    DetectionApp.main(new String[] {});
  }
}
}

我遇到的问题是,由于 @SpringBootTest 注释而进行的 bean 的初始引导似乎可以很好地注入值,我通过添加一些日志记录确认了这一点。当我实际调用 main 方法时,它突然无法访问注入 @Value 注释的字段。知道这里发生了什么吗?我有一个资源文件

测试/资源/application.properties

以及在

src/resources/application.properties

当在测试上下文之外调用 main 方法时,可以很好地注入值。

19:30:50 org.springframework.beans.factory.UnsatisfiedDependencyException:创建 com.notification.configuration.TrackingServiceClientConfig 中定义的名称为 'trackingServiceClient' 的 bean 时出错:通过方法 'trackingServiceClient' 参数 1 表达的依赖关系不满足;嵌套异常是 org.springframework.beans.TypeMismatchException:无法将“java.lang.String”类型的值转换为所需的“int”类型;嵌套异常是 java.lang.NumberFormatException: For input string: "${tracking.connectTimeout}

"

标签: springspring-bootspring-mvcspring-annotations

解决方案


推荐阅读