Spring Boot pozwala nam zastąpić nasze pliki application.properties odpowiednikami YAML. Jednak moje testy wydają się mieć problem. Jeśli dodam adnotację my TestConfiguration
(prosta konfiguracja Java), oczekuje się pliku właściwości.
Na przykład to nie działa:
@PropertySource(value = "classpath:application-test.yml")
Jeśli mam to w moim pliku YAML:
db:
url: jdbc:oracle:thin:@pathToMyDb
username: someUser
password: fakePassword
Wykorzystałbym te wartości w taki sposób:
@Value("${db.username}") String username
Jednak kończy się na takim błędzie:
Could not resolve placeholder 'db.username' in string value "${db.username}"
Jak mogę wykorzystać dobroć YAML również w moich testach?
spring
spring-boot
czeki
źródło
źródło
Odpowiedzi:
Spring-boot ma do tego pomocnika, po prostu dodaj
u góry klas testowych lub abstrakcyjnej nadklasy testu.
Edycja: napisałem tę odpowiedź pięć lat temu. Nie działa z najnowszymi wersjami Spring Boot. Oto, co teraz robię (w razie potrzeby przetłumacz Kotlin na Javę):
zostanie dodany na górze
do kontekstu.
źródło
@SpringJUnitConfig(value = {...}, initializers = {ConfigFileApplicationContextInitializer.class})
Jak zostało wspomniane
@PropertySource
, nie ładuje pliku yaml. Aby obejść ten problem, załaduj plik samodzielnie i dodaj wczytane właściwości doEnvironment
.Realizacja
ApplicationContextInitializer
:Dodaj swój inicjalizator do testu:
źródło
YamlFileApplicationContextInitializer
klasą, w której lokalizacja YAML jest definiowana dla każdego przypadku testowego. Jeśli uważasz, że jest to interesujące, dołącz je do swojej odpowiedzi, a ja usunę swoją. Po prostu daj mi znać w komentarzu pod moją odpowiedzią.@PropertySource
można skonfigurować za pomocąfactory
argumentu. Możesz więc zrobić coś takiego:Gdzie
YamlPropertyLoaderFactory
znajduje się moduł ładujący niestandardową właściwość:Zainspirowany https://stackoverflow.com/a/45882447/4527110
źródło
IllegalStateException
gdy plik nie istnieje zamiast prawidłowegoFileNotFoundException
- więc aby to zadziałało@PropertySource(..., ignoreResourceNotFound = true)
, będziesz musiał przechwycić i obsłużyć ten przypadek:try { return new YamlPropertySourceLoader().load(resource.getResource().getFilename(), resource.getResource(), null); } catch (IllegalStateException e) { throw (IOException) e.getCause(); }
CompositePropertySource propertySource = new CompositePropertySource(name); new YamlPropertySourceLoader().load(resource.getResource().getFilename(), resource.getResource()).stream().forEach(propertySource::addPropertySource); return propertySource;
@PropertySource
obsługuje tylko pliki właściwości (jest to ograniczenie ze Springa, a nie sam rozruch). Zapraszam do otwarcia zgłoszenia żądania funkcji w JIRA .źródło
ApplicationContextInitializer
i dodać go do konfiguracji testowej (po prostu użyj a,YamlPropertySourceLoader
aby ulepszyćEnvironment
). Osobiście wolałbym,@PropertySource
żeby wspierał to zachowanie natywnie.Inną opcją jest ustawienie
spring.config.location
przez@TestPropertySource
:źródło
@TestPropertySource(properties = {"spring.config.location=classpath:application-${test.env}.yml" })
IMO twoja jest najlepszą odpowiedzią ze wszystkich.@TestPropertySource(properties = {"spring.config.location=classpath:application-config.yml,classpath:test-config.yml,..." })
@SpringBootTest
adnotacjęPocząwszy od wersji Spring Boot 1.4, możesz użyć nowej
@SpringBootTest
adnotacji, aby łatwiej to osiągnąć (i ogólnie uprościć konfigurację testu integracji) poprzez załadowanie testów integracji przy użyciu obsługi Spring Boot.Szczegóły na wiosennym blogu .
O ile wiem, oznacza to, że uzyskujesz wszystkie korzyści z zewnętrznej dobroci konfiguracji Spring Boot, tak jak w kodzie produkcyjnym, w tym automatyczne pobieranie konfiguracji YAML ze ścieżki klas.
Domyślnie ta adnotacja będzie
ale w razie potrzeby możesz określić inne klasy konfiguracji.
W tym konkretnym przypadku możesz łączyć się
@SpringBootTest
z,@ActiveProfiles( "test" )
a Spring wybierze konfigurację YAML, pod warunkiem, że jest zgodna z normalnymi standardami nazewnictwa rozruchowego (tjapplication-test.yml
.).Uwaga:
SpringRunner.class
to nowa nazwa dlaSpringJUnit4ClassRunner.class
źródło
Podejście do ładowania właściwości yaml, IMHO można wykonać na dwa sposoby:
za. Możesz umieścić konfigurację w standardowej lokalizacji -
application.yml
w katalogu głównym ścieżki klas - zazwyczajsrc/main/resources
i ta właściwość yaml powinna zostać automatycznie załadowana przez Spring Boot ze spłaszczoną nazwą ścieżki, o której wspomniałeś.b. Drugie podejście jest trochę bardziej rozbudowane, w zasadzie zdefiniuj klasę, która będzie przechowywać twoje właściwości w ten sposób:
Zasadniczo oznacza to, że załaduj plik yaml i zapełnij klasę DbProperties w oparciu o główny element „db”.
Teraz, aby użyć go w dowolnej klasie, będziesz musiał zrobić to:
Każde z tych podejść powinno działać bezproblemowo przy użyciu Spring-boot.
źródło
snakeyaml
jest pobierany jako zależność przechodniaspring-boot-starter
, więc nie powinno być potrzeby dodawania go do twojegopom.xml
lubbuild.gradle
, chyba że masz głęboko zakorzenioną potrzebę użycia innej wersji. :)locations
niepath
, iConfigFileApplicationContextInitializer
jest również wymagane.Znalazłem obejście tego problemu, używając
@ActiveProfiles("test")
i dodając plik application-test.yml do src / test / resources.Skończyło się tak:
Plik application-test.yml zawiera tylko właściwości, które chcę przesłonić z application.yml (które można znaleźć w src / main / resources).
źródło
@Value("${my.property}")
ale działa dobrze, jeśli używamenvironment.getProperty("my.property")
.to dlatego, że nie skonfigurowałeś snakeyml. sprężynowy rozruch jest wyposażony w funkcję @EnableAutoConfiguration. jest też konfiguracja snakeyml, kiedy wywołujesz tę adnotację.
to jest mój sposób:
oto mój test:
źródło
Musiałem wczytać niektóre właściwości do mojego kodu i to działa z spring-boot 1.3.0.RELEASE
źródło
Ładowanie niestandardowego pliku yml z konfiguracją wielu profili w Spring Boot.
1) Dodaj komponent bean właściwości z uruchomieniem SpringBootApplication w następujący sposób
2) Skonfiguruj obiekt Java pojo w następujący sposób
3) Utwórz niestandardowy yml (i umieść go w ścieżce zasobów w następujący sposób, nazwa pliku YML: test-service-config.yml
Np. Config w pliku yml.
źródło
Byłem w szczególnej sytuacji, w której nie mogłem załadować klasy @ConfigurationProperties z powodu niestandardowego nazewnictwa właściwości plików. Na koniec jedyne co zadziałało to (dzięki @Mateusz Balbus):
źródło
Zapraszam do korzystania z mojej biblioteki. Teraz obsługiwane są yaml , toml , hocon .
Źródło: github.com
źródło
To nie jest odpowiedź na pierwotne pytanie, ale alternatywne rozwiązanie na potrzebę innej konfiguracji w teście ...
Zamiast tego
@PropertySource
możesz użyć-Dspring.config.additional-location=classpath:application-tests.yml
.Pamiętaj, że ten przyrostek
tests
nie oznacza profilu ...W tym jednym pliku YAML można określić wiele profili, które mogą dziedziczyć po sobie, przeczytaj więcej tutaj - Rozwiązywanie właściwości dla wielu profili sprężynowych (konfiguracja yaml)
Następnie możesz określić w swoim teście, że aktywne profile (przy użyciu
@ActiveProfiles("profile1,profile2")
) są miejscem, wprofile1,profile2
którymprofile2
po prostu nadpisują (niektóre, nie trzeba zastępować wszystkich) właściwości zprofile1
.źródło
Wypróbowałem wszystkie wymienione pytania, ale wszystkie nie działają w moim zadaniu: używanie określonego pliku yaml do niektórych testów jednostkowych. W moim przypadku działa to tak:
źródło
Nie ma potrzeby dodawania takich jak YamlPropertyLoaderFactory lub YamlFileApplicationContextInitializer. Powinieneś przekonwertować swój pomysł. podobnie jak wspólny projekt wiosenny. Wiesz, nie używam konfiguracji Java. Tylko * .xml
Wykonaj następujące kroki:
Wystarczy dodać plik applicationContext.xml jak
następnie dodaj
do twojego
ApplicationMainClass
.Może to pomóc w skanowaniu pliku application-test.yml
źródło