Testing Spring Boot @ConfigurationProperties

1. Oversikt

I vår forrige guide til @ConfigurationProperties, vi lærte å sette opp og bruke @ConfigurationProperties kommentar med Spring Boot for arbeid med ekstern konfigurasjon.

I denne veiledningen, vi viser hvordan du tester konfigurasjonsklasser som er avhengige av @ConfigurationProperties kommentar for å sikre at konfigurasjonsdataene våre er lastet inn og bundet riktig til deres tilsvarende felt.

2. Avhengigheter

I vårt Maven-prosjekt bruker vi spring-boot-starter og vår-støvel-start-test avhengigheter for å aktivere henholdsvis kjernefjær-API og Spring's test-API:

 org.springframework.boot spring-boot-starter-parent 2.2.2.RELEASE org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test 

La oss også konfigurere prosjektet vårt med bønnevalideringsavhengigheter, siden vi bruker dem senere:

  org.hibernate hibernate-validator javax.el javax.el-api 3.0.0 org.glassfish.web javax.el 2.2.6 

3. Egenskaper som bindes til brukerdefinerte POJOer

Når du arbeider med ekstern konfigurasjon, vi oppretter vanligvis POJOer som inneholder felt som samsvarer med de samsvarende konfigurasjonsegenskapene. Som vi allerede vet, vil Spring da automatisk binde konfigurasjonsegenskapene til Java-klassene vi lager.

Til å begynne med, la oss anta at vi har noen serverkonfigurasjoner i en eiendomsfil vi vil kalle src / test / resources / server-config-test.properties:

server.address.ip = 192.168.0.1 server.resources_path.imgs = / root / imgs

La oss nå definere en enkel konfigurasjonsklasse som tilsvarer den forrige egenskapsfilen:

@Configuration @ConfigurationProperties (prefiks = "server") offentlig klasse ServerConfig {privat adresse adresse; private KartressurserPath; // getters og setters}

og tilsvarende Adresse type:

offentlig klasse Adresse {private String ip; // getters og setters}

Til slutt, la oss injisere ServerConfig POJO i testklassen vår og bekreft at alle feltene er satt riktig:

@ExtendWith (SpringExtension.class) @EnableConfigurationProperties (verdi = ServerConfig.class) @TestPropertySource ("classpath: server-config-test.properties") offentlig klasse BindingPropertiesToUserDefinedPOJOUnitTest {@Autowigert serverConfigurert serverConfigurert serverConfigurert @Test ugyldig givenUserDefinedPOJO_whenBindingPropertiesFile_thenAllFieldsAreSet () {assertEquals ("192.168.0.1", serverConfig.getAddress (). GetIp ()); Kart expectResourcesPath = ny HashMap (); expectResourcesPath.put ("imgs", "/ root / imgs"); assertEquals (expectResourcesPath, serverConfig.getResourcesPath ()); }}

I denne testen har vi brukt følgende merknader:

  • @ExtendWith - integrerer Spring's TestContext-rammeverk med JUnit5
  • @EnableConfigurationProperties - muliggjør støtte for @ConfigurationProperties bønner (i dette tilfellet ServerConfig bønne)
  • @TestPropertySource - spesifiserer en testfil som overstyrer standardverdien application.properties fil

4. @ConfigurationProperties@Bønne Metoder

En annen måte å lage konfigurasjonsbønner på er å bruke @ConfigurationProperties kommentar den @Bønne metoder.

For eksempel følgende getDefaultConfigs () metoden skaper en ServerConfig konfigurasjonsbønne:

@Configuration public class ServerConfigFactory {@Bean (name = "default_bean") @ConfigurationProperties (prefix = "server.default") public ServerConfig getDefaultConfigs () {return new ServerConfig (); }}

Som vi kan se, kan vi konfigurere ServerConfig instans ved hjelp @ConfigurationPropertiesgetDefaultConfigs () uten å måtte redigere ServerConfig klassen selv. Dette kan være spesielt nyttig når du arbeider med en ekstern tredjepartsklasse som har begrenset tilgang.

Deretter la oss definere et eksempel på en ekstern egenskap:

server.default.address.ip = 192.168.0.2

Til slutt, for å be våren bruke ServerConfigFactory klasse når du laster ApplicationContext (derav, opprett vår konfigurasjonsbønne), vil vi legge til @ContextConfiguration kommentar til testklassen:

@ExtendWith (SpringExtension.class) @EnableConfigurationProperties (verdi = ServerConfig.class) @ContextConfiguration (klasser = ServerConfigFactory.class) @TestPropertySource ("classpath: server-config-test.properties") offentlig klasse BindingProperties "QToProperties" default_bean ") privat ServerConfig serverConfig; @Test ugyldig givenBeanAnnotatedMethod_whenBindingProperties_thenAllFieldsAreSet () {assertEquals ("192.168.0.2", serverConfig.getAddress (). GetIp ()); // andre påstander ...}}

5. Validering av egenskaper

For å aktivere bønnevalidering i Spring Boot, vi må kommentere toppnivåklassen med @Validert. Deretter legger vi til det nødvendige javax.validation begrensninger:

@Configuration @ConfigurationProperties (prefix = "validate") @Validated public class MailServer {@NotNull @NotEmpty private Map propertiesMap; @Valid private MailConfig mailConfig = ny MailConfig (); // getters og setters}

Tilsvarende MailConfig klassen har også noen begrensninger:

offentlig klasse MailConfig {@NotBlank @Email privat strengadresse; // getters og setters}

Ved å tilby et gyldig datasett:

validate.propertiesMap.first = prop1 validate.propertiesMap.second = prop2 [e-postbeskyttet]

søknaden starter normalt og enhetstestene våre vil bestå:

@ExtendWith (SpringExtension.class) @EnableConfigurationProperties (value = MailServer.class) @TestPropertySource ("classpath: property-validation-test.properties") public class PropertyValidationUnitTest {@Autowired private MailServer mailServer; privat statisk Validator propertyValidator; @BeforeAll offentlig statisk ugyldig oppsett () {propertyValidator = Validation.buildDefaultValidatorFactory (). GetValidator (); } @Test ugyldig nårBindingPropertiesToValidatedBeans_thenConstrainsAreChecked () {assertEquals (0, propertyValidator.validate (mailServer.getPropertiesMap ()). Size ()); assertEquals (0, propertyValidator.validate (mailServer.getMailConfig ()). size ()); }}

På den andre siden, hvis vi bruker ugyldige egenskaper, vil Spring kaste et IllegalStateException ved oppstart.

For eksempel ved å bruke noen av disse ugyldige konfigurasjonene:

validate.propertiesMap.second = validate.mail_config.address = user1.test

vil føre til at søknaden vår mislykkes, med denne feilmeldingen:

Eiendom: validate.propertiesMap [sekund] Verdi: Årsak: må ikke være tom Eiendom: validate.mailConfig.address Verdi: bruker1.test Årsak: må være en velformet e-postadresse

Legg merke til det vi har brukt @GyldigmailConfig felt for å sikre at MailConfig begrensninger blir sjekket, selv om validate.mailConfig.adresse var ikke definert. Ellers ville våren sette seg mailConfig til null og start applikasjonen normalt.

6. Konvertering av egenskaper

Spring Boot egenskaper konvertering gjør at vi kan konvertere noen egenskaper til bestemte typer.

I denne delen starter vi med å teste konfigurasjonsklasser som bruker Springs innebygde konvertering. Deretter tester vi en tilpasset omformer som vi lager selv.

6.1. Spring Boots standardkonvertering

La oss vurdere følgende datastørrelses- og varighetsegenskaper:

# datastørrelser convert.upload_speed = 500 MB convert.download_speed = 10 # varighet convert.backup_day = 1d convert.backup_hour = 8

Spring Boot vil automatisk binde disse egenskapene til matchingen DataSize og Varighet Enger definert i PropertyConversion konfigurasjonsklasse:

@Configuration @ConfigurationProperties (prefix = "convert") offentlig klasse PropertyConversion {private DataSize uploadSpeed; @DataSizeUnit (DataUnit.GIGABYTES) privat DataSize downloadSpeed; privat varighet backupDay; @DurationUnit (ChronoUnit.HOURS) privat Varighet backupHour; // getters og setters}

La oss nå sjekke konverteringsresultatene:

@ExtendWith (SpringExtension.class) @EnableConfigurationProperties (value = PropertyConversion.class) @ContextConfiguration (classes = CustomCredentialsConverter.class) @TestPropertySource ("classpath: spring-conversion-test.properties") public class SpringPropertiesConversionConvert @Test ugyldig nårUsingSpringDefaultSizeConversion_thenDataSizeObjectIsSet () {assertEquals (DataSize.ofMegabytes (500), propertyConversion.getUploadSpeed ​​()); assertEquals (DataSize.ofGigabytes (10), propertyConversion.getDownloadSpeed ​​()); } @Test ugyldig nårUsingSpringDefaultDurationConversion_thenDurationObjectIsSet () {assertEquals (Duration.ofDays (1), propertyConversion.getBackupDay ()); assertEquals (Duration.ofHours (8), propertyConversion.getBackupHour ()); }}

6.2. Egendefinerte omformere

La oss forestille oss at vi vil konvertere konverter. legitimasjon eiendom:

convert.credentials = bruker, 123

inn i det følgende Legitimasjon klasse:

Legitimasjonsinformasjon for offentlig klasse {private String-brukernavn; privat strengpassord; // getters og setters}

For å oppnå dette kan vi implementere en tilpasset omformer:

@Component @ConfigurationPropertiesBinding offentlig klasse CustomCredentialsConverter implementerer Converter {@Override public Credentials convert (String source) {String [] data = source.split (","); returner nye referanser (data [0], data [1]); }}

Til slutt, la oss legge til en Legitimasjonserklæring felt til PropertyConversion klasse:

offentlig klasse PropertyConversion {private Credentials credentials; // ...}

I vår SpringPropertiesConversionUnitTest testklasse, må vi også legge til @ContextConfiguration for å registrere den tilpassede omformeren i vårs sammenheng:

// andre merknader @ContextConfiguration (klasser = CustomCredentialsConverter.class) offentlig klasse SpringPropertiesConversionUnitTest {// ... @Test ugyldig nårRegisteringCustomCredentialsConverter_thenCredentialsAreParsed () {assertEquals ("bruker", propertyConversion.getCred; assertEquals ("123", propertyConversion.getCredentials (). getPassword ()); }}

Som de foregående påstandene viser, Spring har brukt vår tilpassede omformer til å analysere konverter. legitimasjon eiendom til en Legitimasjonserklæring forekomst.

7. YAML-dokumenter bindende

For hierarkiske konfigurasjonsdata kan YAML-konfigurasjon være mer praktisk. I tillegg støtter YAML å definere flere profiler i samme dokument.

Følgende application.yml ligger under src / test / ressurser / definerer en "test" profil for ServerConfig klasse:

vår: profiler: testserver: adresse: ip: 192.168.0.4 resources_path: imgs: / etc / test / imgs --- # andre profiler

Som et resultat vil følgende test bestå:

@ExtendWith (SpringExtension.class) @ContextConfiguration (initializers = ConfigFileApplicationContextInitializer.class) @EnableConfigurationProperties (value = ServerConfig.class) @ActiveProfiles ("test") public class BindingYMLPropertiesUnitow Server = @ActiveProfiles ("test"); @Test ugyldig nårBindingYMLConfigFile_thenAllFieldsAreSet () {assertEquals ("192.168.0.4", serverConfig.getAddress (). GetIp ()); // andre påstander ...}}

Et par notater angående brukte merknader:

  • @ContextConfiguration (initialiserer = ConfigFileApplicationContextInitializer.class) - laster application.yml fil
  • @ActiveProfiles (“test”) - spesifiserer at "test" -profilen skal brukes under denne testen

Til slutt, la oss huske på det ingen @ProperySource heller ikke @TestProperySource støtte lasting .yml filer. Derfor bør vi alltid plassere YAML-konfigurasjonene våre i application.yml fil.

8. Overstyring @ConfigurationProperties Konfigurasjoner

Noen ganger kan det være lurt å overstyre konfigurasjonsegenskapene som er lastet inn av @ConfigurationProperties med et annet datasett, spesielt når du tester.

Som vi har vist i tidligere eksempler, kan vi bruke @TestPropertySource (“path_to_new_data_set”) for å erstatte hele den opprinnelige konfigurasjonen (under / src / main / resources) med en ny.

Alternativt kan vi selektivt erstatte noen av de originale egenskapene ved hjelp av eiendommer attributt av @TestPropertySource også.

Anta at vi vil overstyre det tidligere definerte validate.mail_config.address eiendom med en annen verdi. Alt vi trenger å gjøre er å kommentere testklassen vår med @TestPropertySource og tilordne deretter en ny verdi til samme eiendom via eiendommer liste:

@TestPropertySource (egenskaper = {"[e-postbeskyttet]"})

Derfor vil Spring bruke den nylig definerte verdien:

assertEquals ("[email protected]", mailServer.getMailConfig (). getAddress ());

9. Konklusjon

I denne veiledningen har vi sett hvordan vi kan teste forskjellige typer konfigurasjonsklasser som bruker @ConfigurationProperties kommentar for å laste .eiendommer og .yml konfigurasjonsfiler.

Som vanlig er kildekoden for denne artikkelen tilgjengelig på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found