Spring Boot: настройка пользовательских свойств и тесты - PullRequest
0 голосов
/ 04 июня 2018

Я использую Spring Boot 2.0 с файлом свойств по умолчанию application.yml.Я хотел бы разделить его на отдельные файлы свойств, потому что он становится огромным.
Также я хотел бы написать тесты для проверки правильности свойств: значения, которые будут представлены в контексте производственного приложения (а не в тестовом).

Вот мой файл свойств: src / main / resources / config / custom.yml

my-property:
  value: 'test'

Класс свойства:

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

Тест:

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

}

Но тест завершается неудачно с ошибкой:

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

Также я вижу, что значение свойства равно null при запуске приложения путем печати его в ApplicationRunner.
Когда я использовал application.yml для всех свойств это было хорошо с той же конфигурацией.

Как правильно настроить свойства и тесты для его работы?
Ссылка на Github repo

Ответы [ 4 ]

0 голосов
/ 28 октября 2018

Я немного опоздал на вечеринку, но это также может помочь.Решение, предоставленное в качестве ответа, пока является наилучшим подходом, но здесь есть альтернатива, которую я использовал

Использовать профили и изменить bean-компонент PropertySoucesPlaceHolderConfiguration для загрузки необходимых файлов свойств на основе профилей.Он загружает application.properties как файл по умолчанию, но другие файлы свойств -oauth_DEV и oauth_QA загружаются на основе установленных профилей

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

, а затем создают еще один bean-компонент, который читает свойства на основе префикса - «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;
    }


}

Помните, что сеттеры важны, потому что ConfigurationProperties загружает значения в свойства класса только тогда, когда определены геттеры и сеттеры

Теперь мы можем автоматически связатьзависимость везде, где это необходимо, и используйте свойство.

0 голосов
/ 04 июня 2018

Если это ваш точный код, который означает, что вы читаете свою собственность из неправильного файла свойств.

замените ресурс вашей собственности на эту строку.

@PropertySource("classpath:config/services.yml")
0 голосов
/ 05 июня 2018

Точно я нашел правильный путь для создания пользовательских свойств yaml в моем приложении.

Проблема в том, что Spring не поддерживает файлы yaml как @PropertySource ( ссылка на выпуск ).И вот обходной путь, как справиться с описанным в весенней документации .
Итак, чтобы иметь возможность загружать свойства из yaml-файлов, вам необходимо:
* Для реализации EnvironmentPostProcessor
* Чтобы зарегистрировать его в spring.factories

Посетите этот репозиторий github для полного примера.

Также, большое спасибо за вашу поддержку, ребята!

0 голосов
/ 04 июня 2018

@TestPropertySource может решить вашу проблему.

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

Надеюсь, это поможет.

...