[英]Spring Boot: How to override default properties in Unit tests
I tried loading a second properties file for my unit tests, that would overwrite some properties. 我尝试为我的单元测试加载第二个属性文件,这将覆盖一些属性。
Loading it with @PropertySource
on a @Configuration
didn't work, loading it with @TestPropertySource
didn't work either. 在@Configuration
上使用@PropertySource
加载它不起作用,使用@TestPropertySource
加载它也不起作用。 Only setting properties
directly on @TesPropertySource
works, but it does NOT work when I try to make it into a meta-annotation. 只能直接在@TesPropertySource
上设置properties
,但是当我尝试将其变成元注释时,它不起作用。
Here is an example project: https://github.com/cptwunderlich/SpringTestProperties 这是一个示例项目: https : //github.com/cptwunderlich/SpringTestProperties
I'd prefer to load one file an affect all tests (eg with @PropertySource
), but if that doesn't work, at least having a custom meta-annotation would be nice, so I don't have to put that on each and every test. 我更喜欢加载一个文件影响所有测试(例如使用@PropertySource
),但如果这不起作用,至少有一个自定义元注释会很好,所以我不必把它放在每个和每一次测试。 Basically I want to not import some data into the DB for the tests (spring.datasource.data) and later also change the database used - without copying the whole config and having to change it in two places each time. 基本上我想一些数据不能导入到数据库的测试(spring.datasource.data)后来也改变使用的数据库-而不复制整个配置,不得不改变它在每次两个地方。
The important bits: 重要的一点:
@RunWith(SpringRunner.class)
@SpringBootTest
@TestPropertySource(locations = "classpath:application-test.properties")
public class TestconfigApplicationTests {
@Value("${my.test.property}")
private String testproperty;
@Test
public void assertValue() {
Assert.assertEquals("foobar", testproperty);
}
}
Alternatively the config class in the tests package : 或者, 测试包中的config类:
@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
@PropertySource("classpath:application-test.properties")
public class GlobalTestConfig {
}
Update: 更新:
The main suggestion in the answers is to use @ActiveProfile
to activate a 'test' profile which will result in loading 'application-test.yaml'. 答案中的主要建议是使用@ActiveProfile
激活'test'配置文件,这将导致加载'application-test.yaml'。 That's bettern than @TestPropertySource
, but I still need to put an annotation on each Test Class. 这比@TestPropertySource
,但我仍然需要在每个Test Class上添加一个注释。 I tried creating a meta-annotation - which should work - so at least I only have one custom annotation where I could bundle other settings. 我尝试创建一个元注释 - 它应该工作 - 所以至少我只有一个自定义注释,我可以捆绑其他设置。 But that doesn't work. 但这不起作用。
The perfect solution would set these setting globally with one config class, instead of having to put an annotation on each test. 完美的解决方案是使用一个配置类全局设置这些设置,而不必在每个测试上添加注释。 I'm still looking for that solution, or at least debugging the meta-annotation before closing this question. 我仍然在寻找这个解决方案,或者至少在关闭这个问题之前调试元注释。
Edit: I've created a Jira issue: SPR-17531
编辑:我创建了一个Jira问题:SPR-17531
Edit 编辑
OK, I got a bit confused, so I retested all the different combinations: 好吧,我有点困惑,所以我重新测试了所有不同的组合:
@TestPropertySource(locations = "classpath:application-test.properties")
on the Test, actually works now. @TestPropertySource(locations = "classpath:application-test.properties")
上的测试,实际上现在的作品 。 huh. 呵呵。 @ActiveProfiles("test")
on the Test works. 关于测试工作的@ActiveProfiles("test")
。 @ActiveProfiles
does not work. 元注解与@ActiveProfiles
不起作用 。 EDIT: it does... 编辑:它确实...... EDIT: 编辑:
OK, my mistake. 好的,我的错误。 The meta-annotation DOES work - I forgot to set the retention policy and the default is CLASS. 元注释可行 - 我忘了设置保留策略,默认为CLASS。 Adding @Retention(RUNTIME)
fixes that. 添加@Retention(RUNTIME)
修复了这个问题。
It doesn't seem like there is a way to globally set this in code (ie, without configuring in my IDE how tests are run), so I'll have to go with the profile for now. 似乎没有办法在代码中全局设置它(即,没有在我的IDE中配置如何运行测试),所以我现在必须使用该配置文件。
You can use @ActiveProfiles("test")
. 您可以使用@ActiveProfiles("test")
。 This will set the application-test.yml
properties into test environment. 这会将application-test.yml
属性设置为测试环境。
@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("test")
public class TestconfigApplicationTests {
...
}
If we need to target different environments, there's a build-in mechanism for that in Boot so there is no need for additional libraries or refactorings. 如果我们需要针对不同的环境,那么在Boot中有一个内置机制,因此不需要额外的库或重构。
We can simply define an application-environment.properties
file in the src/main/resources
directory – and then set a Spring profile with the same environment name. 我们可以简单地在src/main/resources
目录中定义application-environment.properties
文件 - 然后使用相同的环境名称设置Spring配置文件。
For example, if we define a staging
or test
environment, that means we'll have to define a staging or test profile and then application-staging.properties
or application-test.properties
. 例如,如果我们定义一个staging
或test
环境,那意味着我们必须定义一个临时或测试配置文件,然后定义application-staging.properties
或application-test.properties
。
This env
file will be loaded and will take precedence over the default property file which is application.properties
. 此env
文件将被加载,并将优先于默认属性文件application.properties
。 Note that the default file will still be loaded, it's just that when there is a property collision the environment specific property file takes precedence, meaning the properties specified in application-staging.properties
or application-test.properties
will override the ones in application.properties
. 请注意,仍然会加载默认文件,只是当存在属性冲突时,环境特定属性文件优先,这意味着application-staging.properties
或application-test.properties
指定的属性将覆盖application-staging.properties
的属性application.properties
。
Each test class uses its own profile, so you need to specify the active profile for each class. 每个测试类都使用自己的配置文件,因此您需要为每个类指定活动配置文件。
One additional thing that might be of interest for you is that you can mock services via configuration
classes 您可能感兴趣的另一件事是您可以通过configuration
类模拟服务
@Configuration
@Profile("mockEntityService")
public class EntityServiceMockProvider {
@Bean
@Primary
public EntityService entityService() {
EntityService mockedEntityService = Mockito.mock(EntityService.class);
Entity entity= Mockito.mock(Entity.class);
when(mockedEntityService.save(any(Entity.class)))
.thenReturn(entity);
return mockedEntityService ;
}
}
In test classes you can use multiple active profiles: eg @ActiveProfiles({"test", "mockEntityService"})
在测试类中,您可以使用多个活动配置文件:例如@ActiveProfiles({"test", "mockEntityService"})
so instead of using the real implementation of the EntityService
you will use the mocked implementation. 因此,您将使用EntityService
实现,而不是使用EntityService
的实际实现。
You can add application.properties to 您可以将application.properties添加到
src/test/resources
Then all properties which are in this file override these from src/main/resources/application.properties. 然后,此文件中的所有属性都将覆盖src / main / resources / application.properties中的这些属性。
So you don't need profiles and any additional annotations like @TestPropertySource 因此,您不需要配置文件和任何其他注释,如@TestPropertySource
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.