从 Spring Boot 单元测试中排除 Spring Cloud Config Server

Posted

技术标签:

【中文标题】从 Spring Boot 单元测试中排除 Spring Cloud Config Server【英文标题】:Exclude Spring Cloud Config Server from Spring boot unit test 【发布时间】:2018-02-20 01:09:51 【问题描述】:

鉴于我有以下 3 个 Bean:

@Component
public class ServiceConfig 
    // This value is only available from the Spring Cloud Config Server
    @Value("$example.property")
    private String exampleProperty;

    public String getExampleProperty() 
        return exampleProperty;
    


@Component
public class S1 
    int i = 1;


@Component
public class S2 

    @Autowired
    S1 s1;


我希望能够运行以下测试:

@RunWith(SpringRunner.class)
@SpringBootTest
public class S2Test 

    @Autowired
    S2 s;

    @Test
    public void t2() 
        System.out.println(s.s1.i);
    


我遇到的问题是,因为我想单独测试 S2 类并且因为它使用 @Autowired 我必须在我的测试中有一个 Spring 上下文,但是当 Spring 上下文启动时它会尝试创建所有3 个 bean,其中包括带有 @Value 的 bean。由于此值仅可从 Spring Cloud Config Server 获得,因此将无法创建上下文并给出错误:org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'serviceConfig': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'example.property' in string value "$example.property"

我的问题是:如何从 Spring Cloud Config 中读取属性 运行单元测试时在应用程序中处理的服务器,观察 我的测试我什至不关心配置所以我不想明确 必须在我的测试中设置一个值才能启动上下文?

【问题讨论】:

您使用什么作为构建工具? Gradle 还是 Maven?还有什么? 我正在使用 Maven 【参考方案1】:

我建议在“src/test/resources/application.properties”中简单地将“spring.cloud.config.enabled”添加为false,并为“example.property”添加一个测试值..

spring.cloud.config.enabled=false
example.property=testvalue

这很简单,不会影响您的代码库。 如果需要,您还可以使用 MOCK Web 环境和不包含这些 bean 的自定义测试应用程序配置。

@SpringBootTest(classes = TestOnlyApplication.class, webEnvironment = SpringBootTest.WebEnvironment.MOCK)

【讨论】:

没有 spring.cloud.config.enabled=false 也可以正常工作,所以我删除了那个 酷:) 我只在单元测试中禁用它,因为我不希望它们连接到任何东西,但它是否有效并不重要:) @Pytry 它可以在没有spring.cloud.config.enabled=false 的情况下工作,因为当 Spring 看到您的“src/test/resources/application.properties”时,它会停止加载“src/main/resources/application.properties”。 spring.cloud.config.enabled 默认为 false。因此不再使用配置服务器。你能确认一下吗? @ieXcept 我会尝试一下,但我所做的假设是通过使用属性或注释将“spring.cloud.config.enabled”设置为true,所以在测试时将其设置为 false 会覆盖该设置,因为测试“application.properties|yml”优先于主文件。需要注意的是,如果您在 main 中指定了一个值,但在 test 中没有设置 on,那么仍然应该使用 main 中的那个;你只需要设置你想要不同的属性值。 @ieXcept 另外,我认为通常最好使用我的第二个选项编号(创建自定义测试上下文),因为这样可以更好地控制单元测试。【参考方案2】:

有一些选择。

    您可以创建测试配置文件。然后,您需要创建application-test.ymlapplication-test.properties 文件。在那里,您可以为example.property 设置相同的值。在那里,如果您想使用 test 配置文件开始一些测试,您可以添加到您的测试类 @ActiveProfiles("test") 注释。对于这些测试,将启动test

    您可以通过键入@Value("$example.property:SomeDefaultValue") 来设置example.property 的默认值。如果未找到属性,将插入SomeDefaultValue

我建议第一种方法。您可以使用注释设置正确的配置文件,然后您将确定哪个配置文件配置服务器将发送给您。

【讨论】:

这可能有效,但我个人不喜欢使用配置文件和属性的默认值。如果属性不存在,我希望应用程序无法启动。 好的,但是您的应用需要该值,因此您需要以某种方式提供它。我认为正确的测试配置文件是已知的做法(例如用于测试的不同数据源),这就是为什么我会采用第一种方法。实际上,我每天都这样做。 我只是陈述一个偏好,而不是批评:) 我刚刚遇到了太多由于启用了错误的配置文件或未提供预期属性而隐藏错误的实例。我不喜欢配置文件,尤其是因为它们会对应用程序配置产生如此巨大的影响,而我更喜欢细粒度的方法。如果我需要一个属性进行测试,我喜欢将该属性包含在“src/test/resources/application.properties”文件中。如果我的测试需要特殊配置,那么我创建一个仅用于测试的配置类。 是的,当然没问题,我能理解你的方法;)可能在某些情况下这种方法很棒:)我在微服务方面没有太多经验(春天的一个应用程序)云),就个人而言,我真的很喜欢 ymls 中所有模块的所有配置:) 选项 2 是一个坏主意,以防每个运行时环境(开发、生产、测试​​……)中的属性值不同。例如,如果此类属性是数据库连接字符串,并且生产中的应用程序无法从 spring-cloud-config 加载该值,则它可能最终使用指定为默认值的测试数据库连接字符串。

以上是关于从 Spring Boot 单元测试中排除 Spring Cloud Config Server的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot:在单元测试中用一个覆盖多个bean

从 Spring-Boot 测试中排除 elasticsearchTemplate

Java Spring Boot 测试:如何从测试上下文中排除 java 配置类

如何从 Actuator /metrics 端点中排除 Hystrix Metrics?

摇篮 | Spring boot 依赖不排除

在 Spring Boot 测试中排除配置