【问题标题】:Spring: override beans in integration tests with isolationSpring:在集成测试中使用隔离覆盖 bean
【发布时间】:2016-08-16 09:16:47
【问题描述】:

我在 Spring(使用 Spock)的集成测试中覆盖 bean 时遇到问题。

假设这是我的应用程序配置:

@EnableWebMvc
@SpringBootApplication
@Configuration
class Main {
    @Bean
    Race race(Car car) {
        // ...
    }

    @Bean
    Car car() {
        // ...
    }
}

而且我有 2 个单独的集成测试,我想必须分开提供的 Car 实现。

@Slf4j
@SpringApplicationConfiguration
class OneIntegrationSpec extends AbstractIntegrationSpec {

    @Configuration
    @Import(Main.class)
    static class Config {
        @Bean
        Car oneTestCar() {
            return new FerrariCar();
        }
    }
}


@Slf4j
@SpringApplicationConfiguration
class OtherIntegrationSpec extends AbstractIntegrationSpec {

    @Configuration
    @Import(Main.class)
    static class Config {
        @Bean
        Car otherTestCar() {
            return new TeslaCar();
        }
    }
}

当我运行其中一个时,我得到:NoUniqueBeanDefinitionException 因为 Spring 检测到有多个汽车实现。 如何使测试内部类Config@Configuration 注释仅针对该特定测试加载? 我看到了@Profile 的方法,但这意味着为每个IntegrationSpec 创建单独的配置文件名称,这有点违反 DRY。除了@ActiveProfiles,还有其他方法吗?

【问题讨论】:

  • 一个快速而肮脏的解决方案可能是简单地声明您的测试 bean @Primary,这将避免存在多个合适 bean 的事实,因为那时将使用主要候选者。
  • 是的,但是当我在两个*IntegrationSpec 中得到@Primary 时,就会出现同样的问题
  • 你为什么要同时加载两个IntegrationSpecs?您没有显示测试本身(以及您如何加载 Spring 上下文),但可能不要对这些类使用组件扫描。
  • 这是一个spring boot应用,它会自动对整个应用进行组件扫描

标签: java spring spock


【解决方案1】:

我发现很难理解您的用例。是否必须初始化整个 applicationContext 才能测试 FerrariCar 和 TeslaCar?你不能单独测试它们吗?

如果集成测试是唯一的方法,您可以尝试在 @ComponentScan 中使用 excludeFilters 来禁用自动检测您的测试配置,如 https://stackoverflow.com/a/30199808/1553203 所示。然后,您可以使用 @Import/@ComponentScan 为每个 Spec/Test 添加特定的测试 @Configuration。

【讨论】:

    猜你喜欢
    • 2016-06-15
    • 2018-04-04
    • 2018-11-09
    • 2023-04-04
    • 2019-10-31
    • 2019-01-31
    • 2019-08-20
    • 2019-03-07
    • 2017-11-22
    相关资源
    最近更新 更多