Search code examples
javaspring-bootjunitspring-boot-testapplication.properties

@Nested class takes default application.properties values


Could you tell me why if I have integration test like:

@TestPropertySource(properties = {"spring.application.environment=dev"})
@SpringBootTest
class IntegrationTest  {

@Autowired
PropertyConfig propertyConfig;

@Nested
@SpringBootTest
@TestPropertySource(properties = {"spring.application.environment=dev", "spring.application.property=example"})
class ServerLoadConfiguration  {
    
    @Test

    void exampleTest() {
String someProperty = propertyConfig.getSomeProperty(); // old value
        ....
    }
}

for exampleTest I get values of properties from 'default' properties instead of overridden with that one property specified in @TestPropertySource spring.application.property?

If I make @TestPropertySource(properties = {"spring.application.environment=dev", "spring.application.property=example"}) on IntegrationTest level, then nested class have this value applied.


Solution

  • Sorry, cannot reproduce, with:

    1. With simple(st) quickstarter
    2. Simple (java>16) props:
      package com.example.demo;
      
      import org.springframework.boot.context.properties.ConfigurationProperties;
      
      @ConfigurationProperties("my")
      record PropertyConfig(String foo) { }
      
    3. Simple(st) Config:
      package com.example.demo;
      
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.boot.context.properties.EnableConfigurationProperties;
      
      @SpringBootApplication
      @EnableConfigurationProperties(PropertyConfig.class)
      public class DemoApplication {
      
        public static void main(String[] args) {
          SpringApplication.run(DemoApplication.class, args);
        }
      
      }
      
    4. Test:
      package com.example.demo;
      
      import org.junit.jupiter.api.Assertions;
      import org.junit.jupiter.api.Nested;
      import org.junit.jupiter.api.Test;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.boot.test.context.SpringBootTest;
      import org.springframework.context.ApplicationContext;
      import org.springframework.test.context.TestPropertySource;
      
      @SpringBootTest
      @TestPropertySource(properties = {"my.foo=bar"})
      public class DemoApplicationIT {
      
        @Autowired
        private PropertyConfig my;
      
        @Nested
        class InnerDefaultIT {
      
          @Autowired
          private PropertyConfig myInner;
      
          @Test
          void testInner() {
            Assertions.assertNotNull(myInner.foo());
            Assertions.assertEquals(my.foo(), myInner.foo());
          }
        }
      
        @Nested
        @TestPropertySource(properties = {"my.foo=baz"})
        class InnerIT {
      
          @Autowired
          private PropertyConfig myInner;
      
          @Test
          void testInner() {
            Assertions.assertEquals("bar", my.foo());
            Assertions.assertEquals("baz", myInner.foo());
          }
        }
      
        @Test
        void testOuter() {
          Assertions.assertEquals("bar", my.foo());
        }
      
      }
      
      
    5. Passes (as "unit" as "integration"):
      Tests run: 3, Failures: 0, Errors: 0, Skipped: 0