覆盖Junit Test中的默认Spring-Boot application.properties设置

时间:2015-04-16 08:32:53

标签: java unit-testing spring-boot

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

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

我通常会为我的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 {

}

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

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

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

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

}

不幸的是再次没有成功。

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

10 个答案:

答案 0 :(得分:231)

您可以使用@TestPropertySource覆盖application.properties中的值。来自它的javadoc:

  

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

例如:

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

}

答案 1 :(得分:54)

您还可以使用meta-annotations来外部化配置。例如:

@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 { }

答案 2 :(得分:41)

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

@RunWith(SpringRunner.class)
@SpringBootTest

因此,请将test.properties重命名为application.properties以使用自动配置。

  

如果 * only * 需要加载属性文件(进入环境),您还可以使用以下内容,如here所述

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

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

  1. 添加src/main/resources/application-test.properties
  2. 使用@ActiveProfiles("test")注释测试类。
  3. 根据定义的here规则,将application.properties然后 application-test.properties属性加载到测试用例的应用程序上下文中。

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

答案 3 :(得分:6)

简单说明:

如果您和我一样,并且在application.propertiessrc/main/resources中有相同的src/test/resources,并且您很想,为什么在application.properties中您的测试文件夹在主资源中不替代 application.properties,请继续阅读...

如果application.properties下有src/main/resources,而application.properties下有src/test/resources下的application.properties,则取决于您的身分运行测试。文件夹 structure src/main/resourcessrc/test/resources是Maven的体系结构约定,因此,如果您像mvnw test甚至gradlew test这样运行测试,{ application.properties中的{1}}将被拾取,因为 test 类路径将在 main 类路径之前。但是,如果像Eclipse / STS中的src/test/resources一样运行测试,则Run as JUnit Test中的application.properties将被接受,因为 main 类路径先于 test 类路径。

您可以通过打开src/main/resources来检出。

您将看到类似这样的内容:

XXXbin \ javaw.exe -ea -Dfile.encoding = UTF-8 -classpath
XXX \ workspace-spring-tool-suite-4-4.5.1.RELEASE \ project_name \ bin \ main;
XXX \ workspace-spring-tool-suite-4-4.5.1.RELEASE \ project_name \ bin \ test;

您看到 classpath xxx \ main 首先出现,然后出现 xxx \ test 吗?是的,全部与类路径有关:-)

欢呼

答案 4 :(得分:4)

TLDR:

所以我要做的是拥有标准的src/main/resources/application.propertiessrc/test/resources/application-default.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

答案 5 :(得分:1)

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

好处:自动配置测试;

缺点:在C.I.公开“spring.config.name”属性。层

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

  

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

答案 6 :(得分:1)

如果您正在使用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);
    }
}

答案 7 :(得分:0)

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

答案 8 :(得分:0)

如果使用 public void AddContact(string name, string[] phoneNumbers, string streetAddress, string city, string state, string postalCode, CountryValues countrycode) { // get current activity var activity = CrossCurrentActivity.Current.Activity; // create add contact intent var intent = new Intent(Intent.ActionInsert); intent.SetType(ContactsContract.Contacts.ContentType); // add field for contact name intent.PutExtra(ContactsContract.Intents.Insert.Name, name); // Adding more than on phone number if available foreach (string numbers in phoneNumbers) { intent.PutExtra(ContactsContract.Intents.Insert.Phone, numbers); } // pre-populate address fields intent.PutExtra(ContactsContract.CommonDataKinds.StructuredPostal.Street, streetAddress); intent.PutExtra(ContactsContract.CommonDataKinds.StructuredPostal.City, city); intent.PutExtra(ContactsContract.CommonDataKinds.StructuredPostal.Region, state); intent.PutExtra(ContactsContract.CommonDataKinds.StructuredPostal.Postcode, postalCode); intent.PutExtra(ContactsContract.CommonDataKinds.StructuredPostal.Country, countrycode.ToString()); //start activity activity.StartActivity(intent); } 注释,则另一种适用于覆盖测试中某些属性的方法:

@SpringBootTest

答案 9 :(得分:0)

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.jackson.serialization.FAIL_ON_EMPTY_BEANS=false`enter code here`