【问题标题】:Spring-boot default profile for integration tests用于集成测试的 Spring-boot 默认配置文件
【发布时间】:2017-02-03 01:04:47
【问题描述】:

Spring-boot 使用Spring profiles,例如允许为不同的环境进行单独的配置。 我使用此功能的一种方法是配置测试数据库以供集成测试使用。 但是我想知道是否有必要创建我自己的配置文件“测试”并在每个测试文件中明确激活此配置文件? 现在我通过以下方式做到这一点:

  1. 在 src/main/resources 中创建 application-test.properties

  2. 在那里编写测试特定的配置(现在只是数据库名称)

  3. 在每个测试文件中包括:

    @ActiveProfiles("test")
    

有没有更聪明/更简洁的方法?例如默认测试配置文件?

编辑 1:这个问题与 Spring-Boot 1.4.1 相关

【问题讨论】:

    标签: java spring spring-boot


    【解决方案1】:

    据我所知,没有任何内容可以直接解决您的要求 - 但我可以提出一个可以提供帮助的建议:

    您可以使用自己的测试注释,它是由@SpringBootTest@ActiveProfiles("test") 组成的meta annotation。因此,您仍然需要专用配置文件,但要避免将配置文件定义分散到所有测试中。

    此注释将默认为配置文件test,您可以使用元注释覆盖配置文件。

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @SpringBootTest
    @ActiveProfiles
    public @interface MyApplicationTest {
      @AliasFor(annotation = ActiveProfiles.class, attribute = "profiles") String[] activeProfiles() default {"test"};
    }
    

    【讨论】:

    • 如何使用它来声明注释使用的多个活动配置文件?
    【解决方案2】:

    另一种方法是定义一个基本(抽象)测试类,您的实际测试类将扩展它:

    @RunWith(SpringRunner.class)
    @SpringBootTest()
    @ActiveProfiles("staging")
    public abstract class BaseIntegrationTest {
    }
    

    具体测试:

    public class SampleSearchServiceTest extends BaseIntegrationTest{
    
        @Inject
        private SampleSearchService service;
    
        @Test
        public void shouldInjectService(){
            assertThat(this.service).isNotNull();
        }
    } 
    

    这允许您提取的不仅仅是@ActiveProfiles 注释。您还可以为不同类型的集成测试想象更专业的基类,例如数据访问层与服务层,或用于功能专业(常见的@Before@After 方法等)。

    【讨论】:

      【解决方案3】:

      您可以将 application.properties 文件放在您的 test/resources 文件夹中。你设置好了

      spring.profiles.active=test
      

      这是运行测试时的一种默认测试配置文件。

      【讨论】:

      • 如果我想避免设置@ActiveProfiles("test"),我会在我的测试用例中使用这个条目。它不适合你吗?
      • 如果我创建src/test/resources/application.properties 文件,src/main/resources/application.properties 内容在运行测试时会被忽略。
      • @ciastek 您可以添加application-test.properties 进行测试并仅覆盖您需要的属性。
      • @Advicer 除非默认属性指定 spring.profiles.active=test 就像答案所说的那样,否则不会被选中。
      • @OrangeDog 确切地说-也许您可以使用默认情况下处于活动状态的配置文件“默认”。所以你可以在 test/resources/application-default.properties 添加这样一行(当然除非你已经有一个 src/main/application-default.properties 文件:-)
      【解决方案4】:

      一种描述性的方式来做到这一点(事实上,与@Compito 的原始答案相比,这是一个小小的 tweek):

      1. test/resources/application-default.properties 中设置spring.profiles.active=test
      2. 为测试添加 test/resources/application-test.properties 并仅覆盖您需要的属性。

      【讨论】:

      • 这是否意味着类路径中的默认application.properties 也被解析,然后是test/resources/application-default.properties,然后,因为检测到配置文件“test”,test/resources/application-test.properties 被解析?否则它不会解决@ciastek 的问题,正如在@Compito's answer 下评论的那样。
      • 我在使用 Spring Boot 2.4.5 时收到此错误:“从位置 '类路径资源 [application-default.yml]' 导入的属性 'spring.profiles.active' 在特定配置文件中无效资源[来源:类路径资源[application-default.yml]”
      【解决方案5】:

      到 2021 年和 Spring Boot 2.4 我发现的解决方案是拥有 3 个属性文件

      • src/main/resources/application.yml - 包含应用程序的默认道具
      • src/test/resources/application.yml - 将配置文件设置为“测试”,并从“主”导入属性
      • src/test/resources/application-test.yml - 包含特定于测试的配置文件,它将覆盖“main”

      这里是src/test/resources/application.yml的内容:

      # for testing, set default profile to 'test'
      spring.profiles.active: "test"
      # and import the 'main' properties
      spring.config.import: file:src/main/resources/application.yml
      

      比如src/main/resources/application.yml有内容

      ip-address: "10.7.0.1"
      username: admin
      

      src/test/resources/application-test.yml

      ip-address: "999.999.999.999"
      run-integration-test: true
      

      那么(假设没有其他配置文件)...

      运行测试时,

      profiles=test
      --
      ip-address=999.999.999.999
      username=admin
      run-integration-test=true
      

      以及正常运行应用程序时

      profiles=none
      --
      ip-address=10.7.0.1
      username=admin
      run-integration-test <undefined>
      

      注意:如果src/main/resources/application.yml 包含spring.profiles.active: "dev",那么这不会被src/test/resources/application-test.yml 覆盖

      【讨论】:

      • 奇怪的是,没有src/test/resources/application.yml 文件,environment.getActiveProfiles() 仍然会返回正确的测试配置文件,但如果我通过@Value("${spring.profiles.active:}") 注释获得活动配置文件,它将为空。
      【解决方案6】:

      如果你使用maven,你可以在pom.xml中添加这个:

      <build>
          <plugins>
              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-failsafe-plugin</artifactId>
                  <configuration>
                      <argLine>-Dspring.profiles.active=test</argLine>
                  </configuration>
              </plugin>
              ...
      

      然后,maven 应该使用此参数运行您的集成测试 (*IT.java),并且 IntelliJ 将从激活此配置文件开始 - 因此您可以在其中指定所有属性

      application-test.yml
      

      你不应该需要“-default”属性。

      【讨论】:

      • 为我工作,但也必须向surefire插件添加配置以及故障保护。
      【解决方案7】:

      要激活“测试”配置文件,请在 build.gradle 中写入:

          test.doFirst {
              systemProperty 'spring.profiles.active', 'test'
              activeProfiles = 'test'
          }
      

      【讨论】:

        【解决方案8】:

        您可以将您的测试特定属性放入src/test/resources/config/application.properties

        此文件中定义的属性将在测试期间覆盖src/main/resources/application.properties 中定义的属性。

        如需了解更多信息,请查看Spring Boots docs

        【讨论】:

        • 这里的许多好主意对许多情况都很有用。恕我直言 @Matze 答案是这个问题的最简洁和直接的答案,不需要配置文件,不需要修改测试代码......而且日志记录也更干净(在我的情况下,Spring 记录使用方言时令人困惑:org.hibernate.dialect.PostgreSQL93Dialect谢天谢地,当我的测试是使用测试 H2 数据库时)。
        【解决方案9】:

        在我的情况下,我有不同的 application.properties,具体取决于环境,例如:

        application.properties (base file)
        application-dev.properties
        application-qa.properties
        application-prod.properties
        

        application.properties 包含一个属性 spring.profiles.active 来选择正确的文件。

        对于我的集成测试,我在 test/resources 中创建了一个新的 application-test.properties 文件,并带有 @TestPropertySource({ "/application-test.properties" }) 注释,这是负责根据我对这些测试的需要选择我想要的 application.properties 的文件

        【讨论】:

        • 你应该使用@ActiveProfiles,而不是@TestPropertySource
        • 我认为使用@TestPropertiesSource 并不介意。也是在profile测试配置之间加载配置的方式。
        【解决方案10】:

        另一种编程方式:

          import static org.springframework.core.env.AbstractEnvironment.DEFAULT_PROFILES_PROPERTY_NAME;
        
          @BeforeClass
          public static void setupTest() {
            System.setProperty(DEFAULT_PROFILES_PROPERTY_NAME, "test");
          }
        

        效果很好。

        【讨论】:

          【解决方案11】:

          如果您只是想在通过 maven 构建时设置/使用默认配置文件,请传递参数 -Dspring.profiles.active=test 就像

          mvn clean install -Dspring.profiles.active=dev

          【讨论】:

            【解决方案12】:

            我通常使用通用代码和注释为所有集成测试创建一个基类。不要忘记将其设为abstract,以免实例化。例如:

            @SpringBootTest
            @Transactional
            @AutoConfigureMockMvc
            @ActiveProfiles("test")
            public abstract class AbstractControllerTest {
            
                @Autowired
                protected MockMvc mockMvc;
            
                protected ResultActions perform(MockHttpServletRequestBuilder builder) throws Exception {
                    return mockMvc.perform(builder);
                }
            }
            
            // All annotations are inherited
            class AccountControllerTest extends AbstractControllerTest {
            ....
            

            【讨论】:

              【解决方案13】:

              在你的application.properties文件中添加spring.profiles.active=tests,你可以在你的spring boot应用程序中添加多个属性文件,比如application-stage.propertiesapplication-prod.properties等。你可以在你的application.properties文件中指定文件来引用通过添加spring.profiles.active=stagespring.profiles.active=prod

              您还可以通过提供以下命令在运行 Spring Boot 应用程序时传递配置文件:

              java -jar-Dspring.profiles.active=localbuild/libs/turtle-rnr-0.0.1-SNAPSHOT.jar

              根据配置文件名称选择属性文件,在上述情况下传递配置文件local 考虑application-local.properties 文件

              【讨论】:

                猜你喜欢
                • 2019-02-25
                • 1970-01-01
                • 2021-01-24
                • 2016-12-30
                • 2022-01-19
                • 2013-12-31
                • 1970-01-01
                • 1970-01-01
                • 2019-07-11
                相关资源
                最近更新 更多