我有一个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
设置的简单解决方案,我必须忽略它。
答案 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)
[更新:覆盖某些测试属性]
src/main/resources/application-test.properties
。@ActiveProfiles("test")
注释测试类。根据定义的here规则,将application.properties
和然后 application-test.properties
属性加载到测试用例的应用程序上下文中。
答案 3 :(得分:6)
如果您和我一样,并且在application.properties
和src/main/resources
中有相同的src/test/resources
,并且您很想,为什么在application.properties
中您的测试文件夹在主资源中不替代 application.properties
,请继续阅读...
如果application.properties
下有src/main/resources
,而application.properties
下有src/test/resources
下的application.properties
,则取决于您的身分运行测试。文件夹 structure src/main/resources
和src/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)
所以我要做的是拥有标准的src/main/resources/application.properties
和src/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`