Używam Spring Boot 2.0 z plikiem Właściwości application.yml. Chciałbym podzielić go do oddzielnych plików nieruchomości, ponieważ staje się ogromny.
Chciałbym również pisać testy, aby sprawdzić poprawność właściwości: wartości, które będą prezentowane w kontekście aplikacji produkcyjnej (nie testem testowym).

Oto mój plik właściwości: src / main / zasoby / config / custom.yml

my-property:
  value: 'test'

Klasa nieruchomości:

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Data
@Configuration
@ConfigurationProperties(prefix = "my-property")
@PropertySource("classpath:config/custom.yml")
public class MyProperty {

  private String value;
}

Test:

import static org.junit.Assert.assertEquals;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = MyProperty.class)
@EnableConfigurationProperties
public class MyPropertyTest {

  @Autowired
  private MyProperty property;

  @Test
  public void test() {
    assertEquals("test", property.getValue());
  }

}

Ale test nie powiedzie się z błędem:

java.lang.AssertionError: 
Expected :test
Actual   :null

Widzę również, że wartość właściwości jest null podczas uruchamiania aplikacji, drukowając go w ApplicationRunner.
Kiedy użyłem application.yml dla wszystkich właściwości były dobrze z taką samą konfiguracją.

Jak umieścić poprawną konfigurację właściwości i testów, aby to działać?
Link do Github Repo

4
Bullet-tooth 4 czerwiec 2018, 19:10

4 odpowiedzi

Najlepsza odpowiedź

Drobno znalazłem właściwy sposób na posiadanie niestandardowych właściwości YAML w mojej aplikacji.

Problemem jest to, że wiosna nie obsługuje plików yaml jako @PropertySource (Link do wydania). I tutaj jest obejście, jak radzić sobie z tym opisanym w Dokumentacja sprężyna
Aby móc ładować właściwości z potrzebnych plików YAML:
* Aby wdrożyć EnvironmentPostProcessor
* Aby go zarejestrować w spring.factories

Odwiedź to Github Repo dla pełnego przykładu.

Dużo dziękuję za wsparcie, chłopaki!

4
Bullet-tooth 5 czerwiec 2018, 09:35

@TestPropertySource może rozwiązać problem.

@RunWith(SpringRunner.class)
@SpringBootTest(classes = MyProperty.class)
@TestPropertySource(locations="classpath:test.properties")
public class MyPropertyTest {

@Autowired
private MyProperty property;

@Test
public void test() {
   assertEquals("test", property.getValue());
}
}

Mam nadzieję, że to pomoże.

2
Antariksh 4 czerwiec 2018, 16:28

Jestem trochę późno na imprezę, ale może to również pomóc. Rozwiązanie dostarczone jako odpowiedź jest najlepszym podejściem do tej pory, ale tutaj jest alternatywa, którą użyłem

Korzystaj z profili i modyfikuj fasalizaturę PropertySasePlaceholCerconfiguration, aby załadować niezbędne pliki właściwości w oparciu o profile. Ładuje aplikację

@Bean
    public PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurerconfigurer() {

        System.out.println("Inside Placeholder bean");
        PropertySourcesPlaceholderConfigurer cfg = new PropertySourcesPlaceholderConfigurer();
        ClassPathResource cls1=  new ClassPathResource("application.properties");
         ClassPathResource cls2 = null;

        Map<String, Object> propMap = ((ConfigurableEnvironment) ctx.getEnvironment()).getSystemProperties();
        for(Map.Entry<String, Object> entrySet: propMap.entrySet()) {
            System.out.println("Map.Key:"+entrySet.getKey()+"  Map.valiue:"+entrySet.getValue());
        }

        List<String> profiles=  Arrays.asList(ctx.getEnvironment().getActiveProfiles());
        if(profiles == null || profiles.isEmpty()) {
            if(!propMap.containsKey("spring.profiles.active")) {
                cls2 = new ClassPathResource("oauth-default.properties");
            } else {
                cls2 = new ClassPathResource("oauth-"+propMap.get("spring.profiles.active")+".properties");
            }
        }else {
            for(String profile:profiles) {
                if(profile.equalsIgnoreCase("DEV")) {
                    cls2 =  new ClassPathResource("oauth-DEV.properties");
                }else if(profile.equalsIgnoreCase("QA")) {
                    cls2 =  new ClassPathResource("oauth-QA.properties");
                }else if (profile.equalsIgnoreCase("UAT")) {
                    cls2 =  new ClassPathResource("oauth-UAT.properties");
                }else if(profile.equalsIgnoreCase("PROD")){
                    cls2 =  new ClassPathResource("oauth-PROD.properties");
                }else {
                    cls2 = new ClassPathResource("oauth-default.properties");
                }
            }
        }

        cfg.setLocations(cls1,cls2);
        //cfg.setPlaceholderPrefix("#{");
        return cfg;
    }

Następnie utwórz inną fasolę, która odczytuje właściwości oparte na prefiksie - "Security.oauth2.Client"

@Configuration
@ConfigurationProperties(prefix="security.oauth2.client")
public class OauthSecurityConfigurationDto {

    private String clientId;
    private String clientSecret;
    private String scope;
    private String accessTokenUri;
    private String userAuthorizationUri;
    private String grantType;
    private String resourceIds;
    private String registeredRedirectUri;
    private String preEstablishedRedirectUri;
    private String useCurrentUri;
    private String userInfoUri;
    public String getClientId() {
        return clientId;
    }
    public void setClientId(String clientId) {
        this.clientId = clientId;
    }
    public String getClientSecret() {
        return clientSecret;
    }
    public void setClientSecret(String clientSecret) {
        this.clientSecret = clientSecret;
    }
    public String getScope() {
        return scope;
    }
    public void setScope(String scope) {
        this.scope = scope;
    }
    public String getAccessTokenUri() {
        return accessTokenUri;
    }
    public void setAccessTokenUri(String accessTokenUri) {
        this.accessTokenUri = accessTokenUri;
    }
    public String getUserAuthorizationUri() {
        return userAuthorizationUri;
    }
    public void setUserAuthorizationUri(String userAuthorizationUri) {
        this.userAuthorizationUri = userAuthorizationUri;
    }
    public String getGrantType() {
        return grantType;
    }
    public void setGrantType(String grantType) {
        this.grantType = grantType;
    }
    public String getResourceIds() {
        return resourceIds;
    }
    public void setResourceIds(String resourceIds) {
        this.resourceIds = resourceIds;
    }
    public String getRegisteredRedirectUri() {
        return registeredRedirectUri;
    }
    public void setRegisteredRedirectUri(String registeredRedirectUri) {
        this.registeredRedirectUri = registeredRedirectUri;
    }
    public String getPreEstablishedRedirectUri() {
        return preEstablishedRedirectUri;
    }
    public void setPreEstablishedRedirectUri(String preEstablishedRedirectUri) {
        this.preEstablishedRedirectUri = preEstablishedRedirectUri;
    }
    public String getUseCurrentUri() {
        return useCurrentUri;
    }
    public void setUseCurrentUri(String useCurrentUri) {
        this.useCurrentUri = useCurrentUri;
    }
    public String getUserInfoUri() {
        return userInfoUri;
    }
    public void setUserInfoUri(String userInfoUri) {
        this.userInfoUri = userInfoUri;
    }


}

Pamiętaj, że osadnicy są ważne, ponieważ ConfigurationProperties ładuje wartości do właściwości klasy tylko wtedy, gdy definiuje się Galts i Setters

Teraz możemy autowirować zależność wszędzie tam, gdzie potrzebujesz i korzystać z nieruchomości.

1
Joey587 1 listopad 2018, 12:48

Jeśli jest to dokładny kod, który oznacza, że czytasz swoją nieruchomość z niewłaściwego pliku właściwego.

Wymień zasób nieruchomości do tej linii.

@PropertySource("classpath:config/services.yml")
0
Ravat Tailor 4 czerwiec 2018, 16:30