【问题标题】:How to use @TestConfiguration for avoiding src/test/java scanning?如何使用@TestConfiguration 来避免 src/test/java 扫描?
【发布时间】:2019-05-15 19:30:19
【问题描述】:

根据25.3.3. Excluding Test Configuration这个能力存在:

当放置在顶级类上时,@TestConfiguration 表示 src/test/java 中的类不应该被扫描捡起

我在项目的根路径/包src/test/java/com/example/mvctries/ 中创建了@Configuration FilledWithBeanTestConfig@TestConfiguration DummyTestConfig。我的main 包含方法的类故意@ComponentScan 注释只是为了不小心选择FilledWithBeanTestConfig;关于这种情况Spring特别警告:

如果您的应用程序使用组件扫描(例如,如果您使用 @SpringBootApplication 或 @ComponentScan),你可能会发现顶层 您仅为特定测试创建的配置类 不小心到处被捡起来。

我在@WebMvcTest 带注释的测试类中使用了@Import(DummyTestConfig.class),放在src/test/java/com/example/mvctries/controller/ 中;我原以为 @Configuration FilledWithBeanTestConfig 会被忽略,但事实并非如此。将DummyTestConfig 移动到src/test/java/com/example/mvctries/controller/ 也没有帮助。

在测试上述src/test/java 扫描忽略功能时,我做错了什么?
我应该如何正确使用@TestConfiguration 才能使用src/test/java 扫描忽略功能?
我将如何通过仅使用@SpringBootApplication 组件扫描而不是有意 使用@ComponentScan 扫描来测试此功能?

虽然上述问题可能看起来太多,但实际上是提出以下一个问题的另一种方式:如何制作一个项目以清楚地证明@TestConfiguration 的使用如何导致src/test/java 中的类不应该通过扫描来获取

更新

这是示例项目:https://github.com/adrhc/spring-boot-test-checks.git;运行应用程序时使用端口 8083;更好地运行测试类。

【问题讨论】:

  • 你能分享一个示例项目吗?并明确提及您要实现的目标

标签: spring-boot-test


【解决方案1】:

没有filter 属性的@ComponentScan 将始终加载所有@Configuration 类。 @TestConfiguration 仅适用于那个带注释的类,而不适用于整个包/目录。

这似乎是文档中的一个不幸的表述 - 它讨论了 @TestConfigurationsrc/test/java 内部的顶级类而不是the inner class of you test 上的用法。

简而言之:永远不要在没有TypeExcludeFilter 的情况下使用@ComponentScan - 它会开始为您的所有SpringBootTest 测试以及使用切片的测试加载所有内容 - 这超出了首先使用切片的目的。

一旦你摆脱了@ComponentScan(或者一旦你添加了提到的过滤器):

  • @SpringBootTest 将加载所有 @Configuration 类,但不会加载 @TestConfiguration 类。需要时可以使用@Import 选择@TestConfiguration 类。
  • @WebMvcTest 这样的测试切片不会加载任何额外的自定义类/配置,除非您使用@Import 指示它们。如果您使用 @WebMvcTest(或其他切片)进行的所有测试都需要额外配置,那么您可以轻松创建自己的切片或使用 META-INF/spring.factories 文件更改现有切片(不过是一个单独的主题)。

【讨论】:

    【解决方案2】:

    @ComponentScan被应用时,则需要添加excludeFilters以避免误接@TestConfigurations:

    @ComponentScan(value = { "my.base.package" }, excludeFilters = {
            @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
            @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
    public class BootTestConfig { }
    

    供参考:看@SpringBootApplication;它在@ComponentScan 上定义了excludeFilters

    【讨论】:

      猜你喜欢
      • 2012-04-21
      • 2017-03-17
      • 1970-01-01
      • 2018-08-30
      • 2015-05-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多