Spring Boot: How to override default properties in Unit tests












3















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.










share|improve this question

























  • 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
















3















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.










share|improve this question

























  • 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














3












3








3








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.










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 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

















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












2 Answers
2






active

oldest

votes


















4














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.






share|improve this answer


























  • 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



















0














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






share|improve this answer
























  • 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











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
});


}
});














draft saved

draft discarded


















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









4














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.






share|improve this answer


























  • 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
















4














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.






share|improve this answer


























  • 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














4












4








4







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.






share|improve this answer















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.







share|improve this answer














share|improve this answer



share|improve this answer








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



















  • 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













0














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






share|improve this answer
























  • 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
















0














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






share|improve this answer
























  • 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














0












0








0







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






share|improve this answer













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







share|improve this answer












share|improve this answer



share|improve this answer










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



















  • 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


















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

How to change which sound is reproduced for terminal bell?

Can I use Tabulator js library in my java Spring + Thymeleaf project?

Title Spacing in Bjornstrup Chapter, Removing Chapter Number From Contents