首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当我有许多SpringBootTest类时,如何有效地使用嵌套配置类注入依赖项?

当我有许多SpringBootTest类时,如何有效地使用嵌套配置类注入依赖项?
EN

Stack Overflow用户
提问于 2019-10-27 21:18:57
回答 1查看 1.1K关注 0票数 0

这个问题是Can I use code to control the dependency resolution decisions made by ApplicationContext in Spring Boot?的续集

公认的答案是在每个@SpringBootTest测试夹具类中定义一个嵌套类,用@TestConfiguration对其进行注释,并在其中为每个需要解析的bean定义一个工厂方法。嵌套类的影响范围为测试夹具,影响到夹具中的所有测试,但不影响在其他夹具中定义的测试。

这提供了对在每个测试夹具中运行测试时注入到组件中的依赖项的细粒度控制。

这种方法的问题在于它需要在每个测试夹具类中添加一个嵌套的解析器类。这是不可伸缩的。考虑一个有10个测试装置的项目。其中9个使用相同的注入依赖项,而第10个只需要对一个特定接口执行不同的实现。

在这种情况下,我需要将测试配置类复制到9个测试夹具类中,并且只对第10个测试使用第二个配置类。

我需要一种更可伸缩的方法来做这件事。例如,在上述情况下,我希望能够定义两个配置类,一个用于测试夹具使用的两个配置。然后,我希望能够为每个测试夹具指定应该使用的两个配置类中的哪个。我试过:

  1. --我尝试使用@Import注释将一个文本夹具的嵌套配置类导入另一个测试夹具,但是当这样做时,配置类在后者中被忽略。
  2. I还尝试将嵌套配置类移到较高级别,以便它可以用于所有没有将不同的配置类显式定义为嵌套类的测试夹具,但在这种情况下,配置类被所有测试夹具忽略。

因此,总之,我正在寻找一种有效的方法,允许我只编写每个配置类一次,然后选择性地将一个类应用于每个SpringBootTest类,而不需要复制它。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-10-27 22:39:25

经过一些实验,我得到了以下解决方案。我也将添加所有的细节,总结我在the previous question中学到的东西。

背景

我们有两个接口:和IServer

  1. ,IClient: RealClient和IServer
  2. 是IServer的两个实现: RealServer和MockServer.

要求

  1. 产品代码(在main/java中)应该使用两个.
  2. 测试夹具的真正实现(在

中使用@SpringBootTest注释)

代码语言:javascript
复制
- InterfaceTests defines tests that should use a MockServer and a MockClient 
- ClientTests defines tests that should use a MockServer and RealClient to test the RealClient.
- ServerTests defines tests that should use a MockClient and a RealServer to test the RealServer.
- IntegrationTests defines tests that should use a RealServer and a RealClient

从上面可以清楚地看到,模拟/真实客户机/服务器有四个组合,每个组合都需要在代码的某些区域。

解决方案

该解决方案使用@Configuration和@TestConfiguration注解来实现这些需求,而不需要重复代码。

@Component

  • Under main/java实现配置类时,
  1. 不对接口及其实现进行注释,如下所示:

代码语言:javascript
复制
@Configuration
public class RealInjector {
    @Bean
    public IServer createServer(){
        return new RealServer();
    }

    @Bean
    public IClient createClient(){
        return new RealClient();
    }
}

测试/java中的

  1. 实现了这三个测试配置类

代码语言:javascript
复制
@TestConfiguration
public class AllMockInjector {
    @Bean
    public IServer createServer(){
        return new MockServer();
    }

    @Bean
    public IClient createClient(){
        return new MockClient();
    }
}

@TestConfiguration
public class MockServerInjector{
    @Bean
    public IServer createServer(){
        return new MockServer();
    }

    @Bean
    public IClient createClient(){
        return new RealClient();
    }
}

@TestConfiguration
public class MockClientInjector{
    @Bean
    public IServer createServer(){
        return new RealServer();
    }

    @Bean
    public IClient createClient(){
        return new MockClient();
    }
}

  1. 对InterfaceTests测试夹具的注释如下:

代码语言:javascript
复制
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {AllMockInjector.class})
public class InterfaceTests { ... }

  1. 对ClientTests测试夹具的注释如下:

代码语言:javascript
复制
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {MockServerInjector.class})
public class ClientTests { ... }

  1. 对ServerTests测试夹具的注释如下:

代码语言:javascript
复制
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {MockClientInjector.class})
public class ServerTests { ... }

  1. 对IntegrationTests测试夹具的注释如下:

代码语言:javascript
复制
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {RealInjector.class})
public class IntegrationTests { ... }

最后

为了让测试配置类覆盖main/java中的RealInjector配置类,我们需要设置属性:

代码语言:javascript
复制
spring.main.allow-bean-definition-overriding=true 

这样做的一种方法是对上述每个测试夹具进行注释,如下所示:

代码语言:javascript
复制
@SpringBootTest(properties = ["spring.main.allow-bean-definition-overriding=true"])
class TestFixture { ... }

但这是相当冗长的,特别是当你有许多测试装置。相反,您可以在测试/资源下的application.properties文件中添加以下内容:

代码语言:javascript
复制
spring.main.allow-bean-definition-overriding=true

您还可能需要将其添加到application.properties中的main/resources中。

摘要

该解决方案为您提供了对注入到代码中用于生产和测试的实现的细粒度控制。该解决方案不需要代码复制或外部配置文件(除了test/resources/application.properties中的一个属性外)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58583454

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档