Java 覆盖 Junit 测试中的默认 Spring-Boot application.properties 设置

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29669393/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 08:24:31  来源:igfitidea点击:

Override default Spring-Boot application.properties settings in Junit Test

javaunit-testingspring-boot

提问by FrVaBe

I have a Spring-Boot application where the default properties are set in an application.propertiesfile in the classpath (src/main/resources/application.properties).

我有一个 Spring-Boot 应用程序,其中默认属性设置在application.properties类路径 (src/main/resources/application.properties)中的文件中。

I would like to override some default settings in my JUnit test with properties declared in a test.propertiesfile (src/test/resources/test.properties)

我想用test.properties文件 (src/test/resources/test.properties) 中声明的属性覆盖我的 JUnit 测试中的一些默认设置

I usualy have a dedicated Config Class for my Junit Tests, e.g.

我通常有一个专门的配置类用于我的 Junit 测试,例如

package foo.bar.test;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import(CoreConfig.class)
@EnableAutoConfiguration
public class TestConfig {

}

I first thought that using @PropertySource("classpath:test.properties")in the TestConfig class would do the trick, but these properties will not overwrite the application.properties settings (see Spring-Boot Reference Doc - 23. Externalized Configuration).

我首先认为@PropertySource("classpath:test.properties")在 TestConfig 类中使用可以解决问题,但这些属性不会覆盖 application.properties 设置(请参阅 Spring-Boot 参考文档 - 23. 外部化配置)。

Then I tried to use -Dspring.config.location=classpath:test.propertieswhen invoking the test. That was successful - but I don't want to set this system property for each test execution. Thus I put it in the code

然后我尝试-Dspring.config.location=classpath:test.properties在调用测试时使用。这是成功的 - 但我不想为每个测试执行设置这个系统属性。因此我把它放在代码中

@Configuration
@Import(CoreConfig.class)
@EnableAutoConfiguration
public class TestConfig {

  static {
    System.setProperty("spring.config.location", "classpath:test.properties");
  }

}

which unfortunatly was again not successful.

不幸的是,这再次没有成功。

There must be a simple solution on how to override application.propertiessettings in JUnit tests with test.propertiesthat I must have overlooked.

关于如何覆盖application.propertiesJUnit 测试中的设置,必须有一个简单的解决方案test.properties,我必须忽略它。

采纳答案by Andy Wilkinson

You can use @TestPropertySourceto override values in application.properties. From its javadoc:

您可以使用@TestPropertySource来覆盖application.properties. 从它的javadoc:

test property sources can be used to selectively override properties defined in system and application property sources

测试属性源可用于选择性地覆盖系统和应用程序属性源中定义的属性

For example:

例如:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = ExampleApplication.class)
@TestPropertySource(locations="classpath:test.properties")
public class ExampleApplicationTests {

}

回答by Rob Winch

You can also use meta-annotationsto externalize the configuration. For example:

您还可以使用元注释来外部化配置。例如:

@RunWith(SpringJUnit4ClassRunner.class)
@DefaultTestAnnotations
public class ExampleApplicationTests { 
   ...
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@SpringApplicationConfiguration(classes = ExampleApplication.class)
@TestPropertySource(locations="classpath:test.properties")
public @interface DefaultTestAnnotations { }

回答by D. Soloviev

Otherwise we may change the default property configurator name, setting the property spring.config.name=testand then having class-path resource src/test/test.propertiesour native instance of org.springframework.boot.SpringApplicationwill be auto-configured from this separated test.properties, ignoring application properties;

否则,我们可能会更改默认的属性配置器名称,设置属性spring.config.name=test,然后将src/test/test.properties我们的原生实例的类路径资源 org.springframework.boot.SpringApplication从这个分离的 test.properties 中自动配置,忽略应用程序属性;

Benefit: auto-configuration of tests;

优点:自动配置测试;

Drawback: exposing "spring.config.name" property at C.I. layer

缺点:在 CI 层暴露“spring.config.name”属性

ref: http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

参考:http: //docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

spring.config.name=application # Config file name

spring.config.name=application # 配置文件名

回答by Mohnish

Spring Boot automatically loads src/test/resources/application.properties, if following annotations are used

src/test/resources/application.properties如果使用以下注解,Spring Boot 会自动加载

@RunWith(SpringRunner.class)
@SpringBootTest

So, rename test.propertiesto application.propertiesto utilize auto configuration.

因此,重命名test.propertiesapplication.properties使用自动配置。

If you *only*need to load the properties file (into the Environment) you can also use the following, as explained here

@RunWith(SpringRunner.class)
@ContextConfiguration(initializers = ConfigFileApplicationContextInitializer.class) 

如果* *只需要载入属性文件(进入环境),您也可以使用下面的,因为解释这里

@RunWith(SpringRunner.class)
@ContextConfiguration(initializers = ConfigFileApplicationContextInitializer.class) 

[Update: Overriding certain properties for testing]

[更新:覆盖某些属性进行测试]

  1. Add src/main/resources/application-test.properties.
  2. Annotate test class with @ActiveProfiles("test").
  1. 添加src/main/resources/application-test.properties.
  2. @ActiveProfiles("test").

This loads application.propertiesand thenapplication-test.propertiesproperties into application context for the test case, as per rules defined here.

这将根据此处定义的规则加载application.properties然后将application-test.properties属性加载到测试用例的应用程序上下文中。

Demo - https://github.com/mohnish82/so-spring-boot-testprops

演示 - https://github.com/mohnish82/so​​-spring-boot-testprops

回答by elonderin

TLDR:

域名注册地址:

So what I did was to have the standard src/main/resources/application.propertiesand also a src/test/resources/application-default.propertieswhere i override some settings for ALL my tests.

所以我所做的是拥有标准src/main/resources/application.properties以及src/test/resources/application-default.properties我为所有测试覆盖一些设置的地方。

Whole Story

整个故事

I ran into the same problem and was not using profiles either so far. It seemed to be bothersome to have to do it now and remember declaring the profile -- which can be easily forgotten.

我遇到了同样的问题,到目前为止也没有使用配置文件。现在必须这样做并记住声明配置文件似乎很麻烦——这很容易被忘记。

The trick is, to leverage that a profile specific application-<profile>.propertiesoverrides settings in the general profile. See https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-profile-specific-properties.

诀窍是,利用特定application-<profile>.properties于配置文件的覆盖通用配置文件中的设置。请参阅https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-profile-specific-properties

回答by PragmaticFire

You can also create a application.properties file in src/test/resources where your JUnits are written.

您还可以在编写 JUnit 的 src/test/resources 中创建 application.properties 文件。

回答by NimaAJ

Another approach suitable for overriding a few properties in your test, if you are using @SpringBootTestannotation:

如果您使用@SpringBootTest注释,另一种适合覆盖测试中的一些属性的方法:

@SpringBootTest(properties = {"propA=valueA", "propB=valueB"})

回答by Hilal Aissani

I just configured min as the following :

spring.h2.console.enabled=true
spring.h2.console.path=/h2-console


# changing the name of my data base for testing
spring.datasource.url= jdbc:h2:mem:mockedDB
spring.datasource.username=sa
spring.datasource.password=sa



# in testing i don`t need to know the port

#Feature that determines what happens when no accessors are found for a type
#(and there are no annotations to indicate it is meant to be serialized).
spring.Hymanson.serialization.FAIL_ON_EMPTY_BEANS=false`enter code here`

回答by jumping_monkey

If you are like me and you have the same application.propertiesin src/main/resourcesand src/test/resources, and you are wonderingwhy the application.propertiesin your test folder is not overridingthe application.propertiesin your main resources, read on...

如果你像我和你有相同application.propertiessrc/main/resourcessrc/test/resources,和你想知道为什么application.properties在你的测试文件夹没有覆盖application.properties在你的主要资源,阅读...

If you have application.propertiesunder src/main/resourcesand the same application.propertiesunder src/test/resources, which application.propertiesgets picked up, depends on how you are running your tests. The folder structuresrc/main/resourcesand src/test/resources, is a Maven architectural convention, so if you run your test like mvnw testor even gradlew test, the application.propertiesin src/test/resourceswill get picked up, as testclasspath will precede mainclasspath. But, if you run your test like Run as JUnit Testin Elipse/STS, the application.propertiesin src/main/resourceswill get picked up, as mainclasspath precedes testclasspath. You can check it out by opening the Run Configurations...for JUnit, and click on Show Command Line.

如果你有application.propertiessrc/main/resources和相同application.propertiessrc/test/resources,其application.properties被捞起,取决于你如何运行测试。文件夹结构src/main/resourcessrc/test/resources, 是 Maven 架构约定,因此如果您像mvnw test甚至一样运行测试gradlew testapplication.propertiesinsrc/test/resources将被选中,因为测试类路径将在类路径之前。但是,如果您像Run as JUnit Test在 Elipse/STS 中一样运行测试,则application.propertiesinsrc/main/resources将被拾取,因为类路径在测试类路径之前。您可以通过打开Run Configurations...for JUnit来检查它,然后单击Show Command Line

I hope this explanation helps someone.

我希望这个解释对某人有所帮助。

回答by Felipe Desiderati

If you're using Spring 5.2.5 and Spring Boot 2.2.6 and want to override just a few properties instead of the whole file. You can use the new annotation: @DynamicPropertySource

如果您使用的是 Spring 5.2.5 和 Spring Boot 2.2.6,并且只想覆盖几个属性而不是整个文件。您可以使用新注释:@DynamicPropertySource

@SpringBootTest
@Testcontainers
class ExampleIntegrationTests {

    @Container
    static Neo4jContainer<?> neo4j = new Neo4jContainer<>();

    @DynamicPropertySource
    static void neo4jProperties(DynamicPropertyRegistry registry) {
        registry.add("spring.data.neo4j.uri", neo4j::getBoltUrl);
    }
}