Mit Spring Boot können wir unsere application.properties-Dateien durch YAML-Entsprechungen ersetzen. Allerdings scheine ich mit meinen Tests einen Haken zu bekommen. Wenn ich meine TestConfiguration
(eine einfache Java-Konfiguration) kommentiere , erwartet sie eine Eigenschaftendatei.
Zum Beispiel funktioniert das nicht:
@PropertySource(value = "classpath:application-test.yml")
Wenn ich dies in meiner YAML-Datei habe:
db:
url: jdbc:oracle:thin:@pathToMyDb
username: someUser
password: fakePassword
Und ich würde diese Werte mit so etwas nutzen:
@Value("${db.username}") String username
Am Ende habe ich jedoch folgende Fehler:
Could not resolve placeholder 'db.username' in string value "${db.username}"
Wie kann ich die YAML-Güte auch in meinen Tests nutzen?
spring
spring-boot
Scheck
quelle
quelle
Antworten:
Spring-Boot hat einen Helfer dafür, fügen Sie einfach hinzu
an der Spitze Ihrer Testklassen oder einer abstrakten Test-Superklasse.
Edit: Ich habe diese Antwort vor fünf Jahren geschrieben. Es funktioniert nicht mit neueren Versionen von Spring Boot. Dies ist, was ich jetzt mache (bitte übersetzen Sie den Kotlin bei Bedarf nach Java):
wird dann oben hinzugefügt
zum Kontext.
quelle
@SpringJUnitConfig(value = {...}, initializers = {ConfigFileApplicationContextInitializer.class})
Wie bereits erwähnt,
@PropertySource
wird keine Yaml-Datei geladen. Um dieses Problem zu umgehen, laden Sie die Datei selbst und fügen Sie geladene Eigenschaften hinzuEnvironment
.Implementierung
ApplicationContextInitializer
:Fügen Sie Ihren Initialisierer zu Ihrem Test hinzu:
quelle
YamlFileApplicationContextInitializer
Klasse gepostet, in der der YAML-Standort pro Testfall definiert ist. Wenn Sie es interessant finden, können Sie es in Ihre Antwort einfügen, und ich werde meine löschen. Lass es mich einfach in einem Kommentar unter meiner Antwort wissen.@PropertySource
kann durchfactory
Argument konfiguriert werden . Sie können also Folgendes tun:Wo
YamlPropertyLoaderFactory
ist Ihr benutzerdefinierter Eigenschaftslader:Inspiriert von https://stackoverflow.com/a/45882447/4527110
quelle
IllegalStateException
wenn die Datei nicht vorhanden ist, anstatt der richtigen.FileNotFoundException
Damit dies funktioniert@PropertySource(..., ignoreResourceNotFound = true)
, müssen Sie diesen Fall abfangen und behandeln: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
unterstützt nur Eigenschaftendateien (dies ist eine Einschränkung von Spring, nicht Boot selbst). Öffnen Sie ein Feature-Request-Ticket in JIRA .quelle
ApplicationContextInitializer
und es der Testkonfiguration hinzufügen (verwenden Sie einfach aYamlPropertySourceLoader
, um das zu verbessernEnvironment
). Persönlich würde ich es vorziehen, wenn ich@PropertySource
dieses Verhalten nativ unterstützen würde.Eine andere Option ist das
spring.config.location
Durchsetzen von@TestPropertySource
:quelle
@TestPropertySource(properties = {"spring.config.location=classpath:application-${test.env}.yml" })
IMO Ihre ist die beste Antwort von allen.@TestPropertySource(properties = {"spring.config.location=classpath:application-config.yml,classpath:test-config.yml,..." })
@SpringBootTest
Anmerkung benötigenAb Spring Boot 1.4 können Sie die neue
@SpringBootTest
Annotation verwenden, um dies einfacher zu erreichen (und die Einrichtung Ihres Integrationstests im Allgemeinen zu vereinfachen), indem Sie Ihre Integrationstests mithilfe der Spring Boot-Unterstützung booten.Details zum Frühlingsblog .
Soweit ich das beurteilen kann, bedeutet dies, dass Sie alle Vorteile von Spring Boot's nutzen können externen Konfigurationsgüte genau wie in Ihrem Produktionscode nutzen können, einschließlich der automatischen Übernahme der YAML-Konfiguration aus dem Klassenpfad.
Standardmäßig wird diese Anmerkung
Bei Bedarf können Sie jedoch auch andere Konfigurationsklassen angeben.
Für diesen speziellen Fall können Sie kombinieren
@SpringBootTest
mit@ActiveProfiles( "test" )
und Spring Ihre YAML Config abholen, sofern es die normalen Boot - Benennungsstandards folgt (dhapplication-test.yml
).Hinweis:
SpringRunner.class
ist der neue Name fürSpringJUnit4ClassRunner.class
quelle
Der Ansatz zum Laden der Yaml-Eigenschaften, IMHO kann auf zwei Arten erfolgen:
ein. Sie können die Konfiguration normalerweise an einem Standardspeicherort -
application.yml
im Klassenpfadstamm - ablegensrc/main/resources
ablegen. Diese yaml-Eigenschaft sollte automatisch von Spring boot mit dem von Ihnen erwähnten abgeflachten Pfadnamen geladen werden.b. Der zweite Ansatz ist etwas umfangreicher. Definieren Sie im Grunde eine Klasse, um Ihre Eigenschaften folgendermaßen zu speichern:
Im Wesentlichen bedeutet dies, dass die yaml-Datei geladen und die DbProperties-Klasse basierend auf dem Stammelement von "db" gefüllt wird.
Um es jetzt in einer Klasse zu verwenden, müssen Sie Folgendes tun:
Jeder dieser Ansätze sollte mit Spring-Boot für Sie sauber funktionieren.
quelle
snakeyaml
wird sie als transitive Abhängigkeit von eingezogenspring-boot-starter
, sodass es nicht erforderlich sein sollte, sie zu Ihrempom.xml
oder hinzuzufügen, esbuild.gradle
sei denn, Sie haben einen tief verwurzelten Drang, eine andere Version zu verwenden. :)locations
nichtpath
, und dasConfigFileApplicationContextInitializer
ist auch erforderlich.Ich habe eine Problemumgehung gefunden, indem ich verwendet habe
@ActiveProfiles("test")
Problemumgehung ich eine application-test.yml-Datei verwendet und zu src / test / resources hinzugefügt habe.Am Ende sah es so aus:
Die Datei application-test.yml enthält nur die Eigenschaften, die ich aus application.yml überschreiben möchte (die sich in src / main / resources befinden).
quelle
@Value("${my.property}")
aber es funktioniert gut, wenn ich es benutzeenvironment.getProperty("my.property")
.Das liegt daran, dass Sie snakeyml nicht konfiguriert haben. Spring Boot wird mit der Funktion @EnableAutoConfiguration geliefert. Es gibt auch eine Snakeyml-Konfiguration, wenn Sie diese Anmerkung aufrufen.
Das ist mein Weg:
Hier ist mein Test:
quelle
Ich musste einige Eigenschaften in meinen Code einlesen und dies funktioniert mit Spring-Boot 1.3.0.RELEASE
quelle
Laden einer benutzerdefinierten XML-Datei mit mehreren Profilkonfigurationen in Spring Boot.
1) Fügen Sie die Property Bean beim Start von SpringBootApplication wie folgt hinzu
2) Konfigurieren Sie das Java Pojo-Objekt wie folgt
3) Erstellen Sie die benutzerdefinierte XML-Datei (und platzieren Sie sie wie folgt unter dem Ressourcenpfad YML-Dateiname: test-service-config.yml
ZB Config in der yml-Datei.
quelle
Ich befand mich in einer bestimmten Situation, in der ich eine @ ConfigurationProperties-Klasse aufgrund der benutzerdefinierten Benennung von Dateieigenschaften nicht laden konnte. Am Ende hat nur funktioniert (danke @Mateusz Balbus):
quelle
Willkommen in meiner Bibliothek. Jetzt wird Yaml , Toml , Hocon unterstützt.
Quelle: github.com
quelle
Dies ist keine Antwort auf die ursprüngliche Frage, sondern eine alternative Lösung für die Notwendigkeit, in einem Test eine andere Konfiguration zu haben ...
Anstelle von
@PropertySource
Ihnen können verwenden-Dspring.config.additional-location=classpath:application-tests.yml
.Beachten Sie, dass Suffix
tests
nicht Profil bedeutet ...In dieser einen YAML-Datei können mehrere Profile angegeben werden, die voneinander erben können. Lesen Sie hier mehr - Auflösung von Eigenschaften für mehrere Spring-Profile (Yaml-Konfiguration)
Dann können Sie in Ihrem Test angeben, dass aktive Profile (mit
@ActiveProfiles("profile1,profile2")
) sind ,profile1,profile2
woprofile2
einfach außer Kraft gesetzt wird (einige, braucht man nicht alle außer Kraft zu setzen) Eigenschaften ausprofile1
.quelle
Es ist nicht erforderlich, wie YamlPropertyLoaderFactory oder YamlFileApplicationContextInitializer hinzuzufügen. Sie sollten Ihre Idee umsetzen. genau wie ein gewöhnliches Frühlingsprojekt. Sie wissen, dass Sie keine Java-Konfiguration verwenden. Nur * .xml
Folge diesen Schritten:
Fügen Sie einfach applicationContext.xml wie hinzu
dann füge hinzu
zu deinem
ApplicationMainClass
.Dies kann beim Scannen Ihrer application-test.yml helfen
quelle