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.
Only setting properties
directly on @TesPropertySource
works,
but it does NOT work when I try to make it into a meta-annotation.
Here is an example project: https://github.com/cptwunderlich/SpringTestProperties
I'd prefer to load one file an affect all tests (e.g. 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.
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.
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:
@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'.
That's bettern than @TestPropertySource
, but I still need to put an annotation on each 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
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. huh.
@ActiveProfiles("test")
on the Test works.- Meta-annotation with
@ActiveProfiles
does not work. EDIT: it does... - Global config of any sort (TestPropertySource, ActiveProfiles, Propertysource) does not work
- (Having an application.properties in test/resources also doesn't work, bc. it doesn't overwrite single properties, but the complete file, i.e., I'd need to redefine and duplicate everything.)
EDIT:
OK, my mistake. The meta-annotation DOES work - I forgot to set the retention policy and the default is CLASS. Adding @Retention(RUNTIME)
fixes that.
It doesn't seem like there is a way to globally set this in code (i.e., without configuring in my IDE how tests are run), so I'll have to go with the profile for now.
java spring unit-testing spring-boot spring-boot-test
add a comment |
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.
Only setting properties
directly on @TesPropertySource
works,
but it does NOT work when I try to make it into a meta-annotation.
Here is an example project: https://github.com/cptwunderlich/SpringTestProperties
I'd prefer to load one file an affect all tests (e.g. 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.
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.
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:
@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'.
That's bettern than @TestPropertySource
, but I still need to put an annotation on each 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
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. huh.
@ActiveProfiles("test")
on the Test works.- Meta-annotation with
@ActiveProfiles
does not work. EDIT: it does... - Global config of any sort (TestPropertySource, ActiveProfiles, Propertysource) does not work
- (Having an application.properties in test/resources also doesn't work, bc. it doesn't overwrite single properties, but the complete file, i.e., I'd need to redefine and duplicate everything.)
EDIT:
OK, my mistake. The meta-annotation DOES work - I forgot to set the retention policy and the default is CLASS. Adding @Retention(RUNTIME)
fixes that.
It doesn't seem like there is a way to globally set this in code (i.e., without configuring in my IDE how tests are run), so I'll have to go with the profile for now.
java spring unit-testing spring-boot spring-boot-test
I suggest a read of the Spring Boot reference guide on how properties work in Spring Boot (see docs.spring.io/spring-boot/docs/current/reference/html/…). In short use@ActiveProfiles("test")
and spring boot will load bothapplication.properties
andapplication-test.properties
. The latter will override properties from the former.
– M. Deinum
Nov 21 '18 at 11:41
add a comment |
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.
Only setting properties
directly on @TesPropertySource
works,
but it does NOT work when I try to make it into a meta-annotation.
Here is an example project: https://github.com/cptwunderlich/SpringTestProperties
I'd prefer to load one file an affect all tests (e.g. 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.
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.
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:
@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'.
That's bettern than @TestPropertySource
, but I still need to put an annotation on each 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
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. huh.
@ActiveProfiles("test")
on the Test works.- Meta-annotation with
@ActiveProfiles
does not work. EDIT: it does... - Global config of any sort (TestPropertySource, ActiveProfiles, Propertysource) does not work
- (Having an application.properties in test/resources also doesn't work, bc. it doesn't overwrite single properties, but the complete file, i.e., I'd need to redefine and duplicate everything.)
EDIT:
OK, my mistake. The meta-annotation DOES work - I forgot to set the retention policy and the default is CLASS. Adding @Retention(RUNTIME)
fixes that.
It doesn't seem like there is a way to globally set this in code (i.e., without configuring in my IDE how tests are run), so I'll have to go with the profile for now.
java spring unit-testing spring-boot spring-boot-test
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.
Only setting properties
directly on @TesPropertySource
works,
but it does NOT work when I try to make it into a meta-annotation.
Here is an example project: https://github.com/cptwunderlich/SpringTestProperties
I'd prefer to load one file an affect all tests (e.g. 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.
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.
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:
@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'.
That's bettern than @TestPropertySource
, but I still need to put an annotation on each 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
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. huh.
@ActiveProfiles("test")
on the Test works.- Meta-annotation with
@ActiveProfiles
does not work. EDIT: it does... - Global config of any sort (TestPropertySource, ActiveProfiles, Propertysource) does not work
- (Having an application.properties in test/resources also doesn't work, bc. it doesn't overwrite single properties, but the complete file, i.e., I'd need to redefine and duplicate everything.)
EDIT:
OK, my mistake. The meta-annotation DOES work - I forgot to set the retention policy and the default is CLASS. Adding @Retention(RUNTIME)
fixes that.
It doesn't seem like there is a way to globally set this in code (i.e., without configuring in my IDE how tests are run), so I'll have to go with the profile for now.
java spring unit-testing spring-boot spring-boot-test
java spring unit-testing spring-boot spring-boot-test
edited Nov 22 '18 at 14:05
aurelius
2,10421953
2,10421953
asked Nov 21 '18 at 10:08
Benjamin MaurerBenjamin Maurer
1,2631024
1,2631024
I suggest a read of the Spring Boot reference guide on how properties work in Spring Boot (see docs.spring.io/spring-boot/docs/current/reference/html/…). In short use@ActiveProfiles("test")
and spring boot will load bothapplication.properties
andapplication-test.properties
. The latter will override properties from the former.
– M. Deinum
Nov 21 '18 at 11:41
add a comment |
I suggest a read of the Spring Boot reference guide on how properties work in Spring Boot (see docs.spring.io/spring-boot/docs/current/reference/html/…). In short use@ActiveProfiles("test")
and spring boot will load bothapplication.properties
andapplication-test.properties
. The latter will override properties from the former.
– M. Deinum
Nov 21 '18 at 11:41
I suggest a read of the Spring Boot reference guide on how properties work in Spring Boot (see docs.spring.io/spring-boot/docs/current/reference/html/…). In short use
@ActiveProfiles("test")
and spring boot will load both application.properties
and application-test.properties
. The latter will override properties from the former.– M. Deinum
Nov 21 '18 at 11:41
I suggest a read of the Spring Boot reference guide on how properties work in Spring Boot (see docs.spring.io/spring-boot/docs/current/reference/html/…). In short use
@ActiveProfiles("test")
and spring boot will load both application.properties
and application-test.properties
. The latter will override properties from the former.– M. Deinum
Nov 21 '18 at 11:41
add a comment |
2 Answers
2
active
oldest
votes
You can use @ActiveProfiles("test")
. This will set the application-test.yml
properties into test environment.
@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.
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.
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
.
This env
file will be loaded and will take precedence over the default property file which is 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
.
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
@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:
e.g. @ActiveProfiles({"test", "mockEntityService"})
so instead of using the real implementation of the EntityService
you will use the mocked implementation.
TY for your answer. Will this use 'application-test.yml' by default, or do I need to set the name somewhere? Are these ADDITIONAL properties, e.g., they can overwrite existing ones, or do I need to duplicate my whole config? And lastly - where do I put the annotation? On each test class, or on a Config..?
– Benjamin Maurer
Nov 21 '18 at 11:23
I edited my answer to cover your question and some additional material that might help you
– aurelius
Nov 21 '18 at 12:33
Thanks. Well, it seems like putting it on a @Configuration class doesn't do the trick. You have to put it onto the test and creating a meta-annotation fails, even though it should be possible according to docs: docs.spring.io/spring-framework/docs/current/javadoc-api/org/…
– Benjamin Maurer
Nov 21 '18 at 12:55
the @Profile on a configuration creates a new profile configuration like the existence of the application-test property file, that one will create the test profile.
– aurelius
Nov 21 '18 at 13:03
I inadvertedly clicked 'edit' on your answer instead of my question x| But I can't retract it, it's up for review. Hopefully the reviewer catches that...
– Benjamin Maurer
Nov 22 '18 at 12:09
add a comment |
You can add application.properties to
src/test/resources
Then all properties which are in this file override these from src/main/resources/application.properties.
So you don't need profiles and any additional annotations like @TestPropertySource
No, this will replace application.properties completely, i.e., you can't just put the ones you want to overwrite in there, you need to duplicate and change the whole config. I want to avoid this, bc. this will inevitably lead to a divergence and bugs.
– Benjamin Maurer
Nov 22 '18 at 10:50
Could you try it? I have this configuration for app with spring-boot 1.5.12 and application.properties in test/resources have only few property. And all properties which are in main/resourceshave their original value
– marok
Nov 22 '18 at 10:56
I've tested it before, I retested it again - just for you - and it still doesn't work. You can try it yourself. I linked a Github repo. Check it out, rename the application-test.properties and see for yourself.
– Benjamin Maurer
Nov 22 '18 at 12:05
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53409635%2fspring-boot-how-to-override-default-properties-in-unit-tests%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
You can use @ActiveProfiles("test")
. This will set the application-test.yml
properties into test environment.
@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.
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.
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
.
This env
file will be loaded and will take precedence over the default property file which is 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
.
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
@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:
e.g. @ActiveProfiles({"test", "mockEntityService"})
so instead of using the real implementation of the EntityService
you will use the mocked implementation.
TY for your answer. Will this use 'application-test.yml' by default, or do I need to set the name somewhere? Are these ADDITIONAL properties, e.g., they can overwrite existing ones, or do I need to duplicate my whole config? And lastly - where do I put the annotation? On each test class, or on a Config..?
– Benjamin Maurer
Nov 21 '18 at 11:23
I edited my answer to cover your question and some additional material that might help you
– aurelius
Nov 21 '18 at 12:33
Thanks. Well, it seems like putting it on a @Configuration class doesn't do the trick. You have to put it onto the test and creating a meta-annotation fails, even though it should be possible according to docs: docs.spring.io/spring-framework/docs/current/javadoc-api/org/…
– Benjamin Maurer
Nov 21 '18 at 12:55
the @Profile on a configuration creates a new profile configuration like the existence of the application-test property file, that one will create the test profile.
– aurelius
Nov 21 '18 at 13:03
I inadvertedly clicked 'edit' on your answer instead of my question x| But I can't retract it, it's up for review. Hopefully the reviewer catches that...
– Benjamin Maurer
Nov 22 '18 at 12:09
add a comment |
You can use @ActiveProfiles("test")
. This will set the application-test.yml
properties into test environment.
@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.
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.
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
.
This env
file will be loaded and will take precedence over the default property file which is 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
.
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
@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:
e.g. @ActiveProfiles({"test", "mockEntityService"})
so instead of using the real implementation of the EntityService
you will use the mocked implementation.
TY for your answer. Will this use 'application-test.yml' by default, or do I need to set the name somewhere? Are these ADDITIONAL properties, e.g., they can overwrite existing ones, or do I need to duplicate my whole config? And lastly - where do I put the annotation? On each test class, or on a Config..?
– Benjamin Maurer
Nov 21 '18 at 11:23
I edited my answer to cover your question and some additional material that might help you
– aurelius
Nov 21 '18 at 12:33
Thanks. Well, it seems like putting it on a @Configuration class doesn't do the trick. You have to put it onto the test and creating a meta-annotation fails, even though it should be possible according to docs: docs.spring.io/spring-framework/docs/current/javadoc-api/org/…
– Benjamin Maurer
Nov 21 '18 at 12:55
the @Profile on a configuration creates a new profile configuration like the existence of the application-test property file, that one will create the test profile.
– aurelius
Nov 21 '18 at 13:03
I inadvertedly clicked 'edit' on your answer instead of my question x| But I can't retract it, it's up for review. Hopefully the reviewer catches that...
– Benjamin Maurer
Nov 22 '18 at 12:09
add a comment |
You can use @ActiveProfiles("test")
. This will set the application-test.yml
properties into test environment.
@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.
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.
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
.
This env
file will be loaded and will take precedence over the default property file which is 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
.
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
@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:
e.g. @ActiveProfiles({"test", "mockEntityService"})
so instead of using the real implementation of the EntityService
you will use the mocked implementation.
You can use @ActiveProfiles("test")
. This will set the application-test.yml
properties into test environment.
@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.
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.
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
.
This env
file will be loaded and will take precedence over the default property file which is 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
.
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
@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:
e.g. @ActiveProfiles({"test", "mockEntityService"})
so instead of using the real implementation of the EntityService
you will use the mocked implementation.
edited Nov 21 '18 at 12:32
answered Nov 21 '18 at 10:16
aureliusaurelius
2,10421953
2,10421953
TY for your answer. Will this use 'application-test.yml' by default, or do I need to set the name somewhere? Are these ADDITIONAL properties, e.g., they can overwrite existing ones, or do I need to duplicate my whole config? And lastly - where do I put the annotation? On each test class, or on a Config..?
– Benjamin Maurer
Nov 21 '18 at 11:23
I edited my answer to cover your question and some additional material that might help you
– aurelius
Nov 21 '18 at 12:33
Thanks. Well, it seems like putting it on a @Configuration class doesn't do the trick. You have to put it onto the test and creating a meta-annotation fails, even though it should be possible according to docs: docs.spring.io/spring-framework/docs/current/javadoc-api/org/…
– Benjamin Maurer
Nov 21 '18 at 12:55
the @Profile on a configuration creates a new profile configuration like the existence of the application-test property file, that one will create the test profile.
– aurelius
Nov 21 '18 at 13:03
I inadvertedly clicked 'edit' on your answer instead of my question x| But I can't retract it, it's up for review. Hopefully the reviewer catches that...
– Benjamin Maurer
Nov 22 '18 at 12:09
add a comment |
TY for your answer. Will this use 'application-test.yml' by default, or do I need to set the name somewhere? Are these ADDITIONAL properties, e.g., they can overwrite existing ones, or do I need to duplicate my whole config? And lastly - where do I put the annotation? On each test class, or on a Config..?
– Benjamin Maurer
Nov 21 '18 at 11:23
I edited my answer to cover your question and some additional material that might help you
– aurelius
Nov 21 '18 at 12:33
Thanks. Well, it seems like putting it on a @Configuration class doesn't do the trick. You have to put it onto the test and creating a meta-annotation fails, even though it should be possible according to docs: docs.spring.io/spring-framework/docs/current/javadoc-api/org/…
– Benjamin Maurer
Nov 21 '18 at 12:55
the @Profile on a configuration creates a new profile configuration like the existence of the application-test property file, that one will create the test profile.
– aurelius
Nov 21 '18 at 13:03
I inadvertedly clicked 'edit' on your answer instead of my question x| But I can't retract it, it's up for review. Hopefully the reviewer catches that...
– Benjamin Maurer
Nov 22 '18 at 12:09
TY for your answer. Will this use 'application-test.yml' by default, or do I need to set the name somewhere? Are these ADDITIONAL properties, e.g., they can overwrite existing ones, or do I need to duplicate my whole config? And lastly - where do I put the annotation? On each test class, or on a Config..?
– Benjamin Maurer
Nov 21 '18 at 11:23
TY for your answer. Will this use 'application-test.yml' by default, or do I need to set the name somewhere? Are these ADDITIONAL properties, e.g., they can overwrite existing ones, or do I need to duplicate my whole config? And lastly - where do I put the annotation? On each test class, or on a Config..?
– Benjamin Maurer
Nov 21 '18 at 11:23
I edited my answer to cover your question and some additional material that might help you
– aurelius
Nov 21 '18 at 12:33
I edited my answer to cover your question and some additional material that might help you
– aurelius
Nov 21 '18 at 12:33
Thanks. Well, it seems like putting it on a @Configuration class doesn't do the trick. You have to put it onto the test and creating a meta-annotation fails, even though it should be possible according to docs: docs.spring.io/spring-framework/docs/current/javadoc-api/org/…
– Benjamin Maurer
Nov 21 '18 at 12:55
Thanks. Well, it seems like putting it on a @Configuration class doesn't do the trick. You have to put it onto the test and creating a meta-annotation fails, even though it should be possible according to docs: docs.spring.io/spring-framework/docs/current/javadoc-api/org/…
– Benjamin Maurer
Nov 21 '18 at 12:55
the @Profile on a configuration creates a new profile configuration like the existence of the application-test property file, that one will create the test profile.
– aurelius
Nov 21 '18 at 13:03
the @Profile on a configuration creates a new profile configuration like the existence of the application-test property file, that one will create the test profile.
– aurelius
Nov 21 '18 at 13:03
I inadvertedly clicked 'edit' on your answer instead of my question x| But I can't retract it, it's up for review. Hopefully the reviewer catches that...
– Benjamin Maurer
Nov 22 '18 at 12:09
I inadvertedly clicked 'edit' on your answer instead of my question x| But I can't retract it, it's up for review. Hopefully the reviewer catches that...
– Benjamin Maurer
Nov 22 '18 at 12:09
add a comment |
You can add application.properties to
src/test/resources
Then all properties which are in this file override these from src/main/resources/application.properties.
So you don't need profiles and any additional annotations like @TestPropertySource
No, this will replace application.properties completely, i.e., you can't just put the ones you want to overwrite in there, you need to duplicate and change the whole config. I want to avoid this, bc. this will inevitably lead to a divergence and bugs.
– Benjamin Maurer
Nov 22 '18 at 10:50
Could you try it? I have this configuration for app with spring-boot 1.5.12 and application.properties in test/resources have only few property. And all properties which are in main/resourceshave their original value
– marok
Nov 22 '18 at 10:56
I've tested it before, I retested it again - just for you - and it still doesn't work. You can try it yourself. I linked a Github repo. Check it out, rename the application-test.properties and see for yourself.
– Benjamin Maurer
Nov 22 '18 at 12:05
add a comment |
You can add application.properties to
src/test/resources
Then all properties which are in this file override these from src/main/resources/application.properties.
So you don't need profiles and any additional annotations like @TestPropertySource
No, this will replace application.properties completely, i.e., you can't just put the ones you want to overwrite in there, you need to duplicate and change the whole config. I want to avoid this, bc. this will inevitably lead to a divergence and bugs.
– Benjamin Maurer
Nov 22 '18 at 10:50
Could you try it? I have this configuration for app with spring-boot 1.5.12 and application.properties in test/resources have only few property. And all properties which are in main/resourceshave their original value
– marok
Nov 22 '18 at 10:56
I've tested it before, I retested it again - just for you - and it still doesn't work. You can try it yourself. I linked a Github repo. Check it out, rename the application-test.properties and see for yourself.
– Benjamin Maurer
Nov 22 '18 at 12:05
add a comment |
You can add application.properties to
src/test/resources
Then all properties which are in this file override these from src/main/resources/application.properties.
So you don't need profiles and any additional annotations like @TestPropertySource
You can add application.properties to
src/test/resources
Then all properties which are in this file override these from src/main/resources/application.properties.
So you don't need profiles and any additional annotations like @TestPropertySource
answered Nov 22 '18 at 10:36
marokmarok
852616
852616
No, this will replace application.properties completely, i.e., you can't just put the ones you want to overwrite in there, you need to duplicate and change the whole config. I want to avoid this, bc. this will inevitably lead to a divergence and bugs.
– Benjamin Maurer
Nov 22 '18 at 10:50
Could you try it? I have this configuration for app with spring-boot 1.5.12 and application.properties in test/resources have only few property. And all properties which are in main/resourceshave their original value
– marok
Nov 22 '18 at 10:56
I've tested it before, I retested it again - just for you - and it still doesn't work. You can try it yourself. I linked a Github repo. Check it out, rename the application-test.properties and see for yourself.
– Benjamin Maurer
Nov 22 '18 at 12:05
add a comment |
No, this will replace application.properties completely, i.e., you can't just put the ones you want to overwrite in there, you need to duplicate and change the whole config. I want to avoid this, bc. this will inevitably lead to a divergence and bugs.
– Benjamin Maurer
Nov 22 '18 at 10:50
Could you try it? I have this configuration for app with spring-boot 1.5.12 and application.properties in test/resources have only few property. And all properties which are in main/resourceshave their original value
– marok
Nov 22 '18 at 10:56
I've tested it before, I retested it again - just for you - and it still doesn't work. You can try it yourself. I linked a Github repo. Check it out, rename the application-test.properties and see for yourself.
– Benjamin Maurer
Nov 22 '18 at 12:05
No, this will replace application.properties completely, i.e., you can't just put the ones you want to overwrite in there, you need to duplicate and change the whole config. I want to avoid this, bc. this will inevitably lead to a divergence and bugs.
– Benjamin Maurer
Nov 22 '18 at 10:50
No, this will replace application.properties completely, i.e., you can't just put the ones you want to overwrite in there, you need to duplicate and change the whole config. I want to avoid this, bc. this will inevitably lead to a divergence and bugs.
– Benjamin Maurer
Nov 22 '18 at 10:50
Could you try it? I have this configuration for app with spring-boot 1.5.12 and application.properties in test/resources have only few property. And all properties which are in main/resourceshave their original value
– marok
Nov 22 '18 at 10:56
Could you try it? I have this configuration for app with spring-boot 1.5.12 and application.properties in test/resources have only few property. And all properties which are in main/resourceshave their original value
– marok
Nov 22 '18 at 10:56
I've tested it before, I retested it again - just for you - and it still doesn't work. You can try it yourself. I linked a Github repo. Check it out, rename the application-test.properties and see for yourself.
– Benjamin Maurer
Nov 22 '18 at 12:05
I've tested it before, I retested it again - just for you - and it still doesn't work. You can try it yourself. I linked a Github repo. Check it out, rename the application-test.properties and see for yourself.
– Benjamin Maurer
Nov 22 '18 at 12:05
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53409635%2fspring-boot-how-to-override-default-properties-in-unit-tests%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
I suggest a read of the Spring Boot reference guide on how properties work in Spring Boot (see docs.spring.io/spring-boot/docs/current/reference/html/…). In short use
@ActiveProfiles("test")
and spring boot will load bothapplication.properties
andapplication-test.properties
. The latter will override properties from the former.– M. Deinum
Nov 21 '18 at 11:41