wake-up-neo.com

Spring Boot: Konfiguration und Tests benutzerdefinierter Eigenschaften

Ich verwende Spring Boot 2.0 mit der Standardeigenschaftendatei application.yml. Ich möchte es teilen, um Eigenschaftendateien zu trennen, weil es sehr groß wird.
Außerdem möchte ich Tests schreiben, um die Richtigkeit der Eigenschaften zu überprüfen: Werte, die im Kontext der Produktionsanwendung angezeigt werden (nicht im Testkontext).

Hier ist meine Eigenschaftendatei: src/main/resources/config/custom.yml

my-property:
  value: 'test'

Objektklasse:

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

Prüfung:

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

}

Aber der Test schlägt mit Fehler fehl:

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

Ich sehe auch, dass der Eigenschaftswert null ist, wenn die Anwendung ausgeführt wird, indem sie in ApplicationRunner gedruckt wird.
Als ich application.yml für alle Eigenschaften verwendete, war es gut mit der gleichen Konfiguration.

Wie stelle ich die richtige Konfiguration für Eigenschaften und Tests ein, damit es funktioniert?
Link zu Github repo

4
Bullet-tooth

Ich habe den richtigen Weg gefunden, um benutzerdefinierte Yaml-Eigenschaften in meiner App zu haben.

Das Problem ist, dass Spring keine yaml-Dateien als @PropertySource unterstützt ( Link zu issue ). Und hier ist eine Problemumgehung, wie Sie mit der in Frühlingsdokumentation beschriebenen umgehen können.
Um also Eigenschaften aus Yaml-Dateien laden zu können, benötigen Sie:
* Um EnvironmentPostProcessor zu implementieren
* Um es in spring.factories zu registrieren

Bitte besuchen Sie diese Github Repo für ein vollständiges Beispiel.

Vielen Dank auch für eure Unterstützung, Leute!

3
Bullet-tooth

@TestPropertySource kann Ihr Problem lösen.

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

Ich hoffe es hilft.

2
Antariksh

Ich bin ein bisschen zu spät zur Party, aber das könnte auch helfen. Die als Antwort bereitgestellte Lösung ist der beste Ansatz, aber hier ist eine Alternative, die ich verwendet habe

Verwenden Sie Profile und ändern Sie die Bean PropertySoucesPlaceHolderConfiguration, um die erforderlichen Eigenschaftendateien basierend auf den Profilen zu laden. Es lädt die application.properties als Standard, aber die anderen Eigenschaftendateien -oauth_DEV und oauth_QA werden basierend auf den festgelegten Profilen geladen

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

Erstellen Sie dann eine weitere Bean, die die Eigenschaften basierend auf dem Präfix "security.oauth2.client" liest.

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


}

Denken Sie daran, dass die Setter wichtig sind, da die ConfigurationProperties die Werte nur dann in die Eigenschaften der Klasse lädt, wenn Getters und Setter definiert sind

Jetzt können wir die Abhängigkeit nach Bedarf automatisch verdrahten und die Eigenschaft verwenden.

1
Joey587

Wenn dies Ihr genauer Code ist, bedeutet dies, dass Sie Ihre Eigenschaft aus einer falschen Eigenschaftendatei lesen.

ersetzen Sie Ihre Eigenschaftsressource in dieser Zeile.

@PropertySource("classpath:config/services.yml")
0
Ravat Tailor