Testiranje proljetnog pokretanja @ConfigurationProperties
1. Pregled
U našem prethodnom vodiču za @ConfigurationProperties, naučili smo kako postaviti i koristiti @ConfigurationProperties napomena s Spring Boot-om za rad s vanjskom konfiguracijom.
U ovom vodiču, pokazat ćemo kako testirati klase konfiguracije koje se oslanjaju na @ConfigurationProperties bilješka kako bismo bili sigurni da su naši podaci o konfiguraciji učitani i ispravno vezani za njihova odgovarajuća polja.
2. Ovisnosti
U našem projektu Maven koristit ćemo opruga-čizma-starter i proljetni-boot-starter-test ovisnosti za omogućavanje jezgrenog API-ja za proljeće i Spring-ovog API-ja za testiranje:
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
Također, konfigurirajmo naš projekt s ovisnostima o provjeri graha jer ćemo ih koristiti kasnije:
org.hibernate hibernate-validator javax.el javax.el-api 3.0.0 org.glassfish.web javax.el 2.2.6
3. Svojstva koja se vežu za korisničke POJO-ove
Kada radite s eksterniziranom konfiguracijom, obično izrađujemo POJO-a koji sadrže polja koja odgovaraju odgovarajućim svojstvima konfiguracije. Kao što već znamo, Spring će tada automatski povezati svojstva konfiguracije s Java klasama koje kreiramo.
Za početak, pretpostavimo da imamo neku konfiguraciju poslužitelja unutar datoteke svojstava koju ćemo nazvati src / test / resources / server-config-test.properties:
server.address.ip = 192.168.0.1 server.resources_path.imgs = / root / imgs
Sada, definirajmo jednostavnu klasu konfiguracije koja odgovara prethodnoj datoteci svojstava:
@Configuration @ConfigurationProperties (prefix = "server") javna klasa ServerConfig {adresa privatne adrese; privatna karta resourcesPath; // geteri i postavljači}
a također i odgovarajuće Adresa tip:
javna klasa Adresa {private String ip; // geteri i postavljači}
Napokon, ubrizgajmo ServerConfig POJO u našu test klasu i potvrdite da su sva njegova polja ispravno postavljena:
@ExtendWith (SpringExtention.class) @EnableConfigurationProperties (value = ServerConfig.class) @TestPropertySource ("classpath: server-config-test.properties") javna klasa BindingPropertiesToUserDefinedPOJOUnitTest {@Autowired private ServerCfononigig privateCigonigig; @Test void givenUserDefinedPOJO_whenBindingPropertiesFile_thenAllFieldsAreSet () {assertEquals ("192.168.0.1", serverConfig.getAddress (). GetIp ()); Karta očekujteResourcesPath = nova HashMap (); očekivaniResourcesPath.put ("imgs", "/ root / imgs"); assertEquals (očekuje seResourcesPath, serverConfig.getResourcesPath ()); }}
U ovom smo testu koristili sljedeće bilješke:
- @ExtendWith - integrira Springov testContext okvir s JUnit5
- @EnableConfigurationProperties - omogućuje podršku za @ConfigurationProperties grah (u ovom slučaju, ServerConfig grah)
- @TestPropertySource - navodi datoteku za testiranje koja poništava zadani primjena.svojstva datoteka
4. @ConfigurationProperties na @Grah Metode
Drugi način stvaranja konfiguracijskog graha je pomoću @ConfigurationProperties bilješka na @Grah metode.
Na primjer, sljedeće getDefaultConfigs () metoda stvara a ServerConfig grah za konfiguraciju:
@Configuration javna klasa ServerConfigFactory {@Bean (name = "default_bean") @ConfigurationProperties (prefix = "server.default") public ServerConfig getDefaultConfigs () {return new ServerConfig (); }}
Kao što vidimo, u mogućnosti smo konfigurirati ServerConfig instanci pomoću @ConfigurationProperties na getDefaultConfigs () metodu, bez potrebe za uređivanjem ServerConfig sama klasa. To može biti posebno korisno kada radite s vanjskom klasom treće strane koja ima ograničeni pristup.
Dalje, definirajmo primjer vanjskog svojstva:
server.default.address.ip = 192.168.0.2
Konačno, da proljeću kažem da koristi ServerConfigFactory klasa prilikom učitavanja ApplicationContext (dakle, stvorite naš konfiguracijski grah), mi ćemo dodati @ContextConfiguration bilješka na ispitnoj klasi:
@ExtendWith (SpringExtension.class) @EnableConfigurationProperties (value = ServerConfig.class) @ContextConfiguration (classes = ServerConfigFactory.class) @TestPropertySource ("classpath: server-config-test.properties"). default_bean ") private ServerConfig serverConfig; @Test void givenBeanAnnotatedMethod_whenBindingProperties_thenAllFieldsAreSet () {assertEquals ("192.168.0.2", serverConfig.getAddress (). GetIp ()); // ostale tvrdnje ...}}
5. Provjera svojstava
Da biste omogućili provjeru graha u Spring Boot-u, moramo označiti razred najviše razine s @Validirano. Zatim dodamo traženo javax.valifikacija ograničenja:
@Configuration @ConfigurationProperties (prefix = "validate") @Validated public class MailServer {@NotNull @NotEmpty private Map propertiesMap; @Valid private MailConfig mailConfig = new MailConfig (); // geteri i postavljači}
Slično tome, MailConfig klasa također ima neka ograničenja:
javna klasa MailConfig {@NotBlank @Email adresa privatnog niza; // geteri i postavljači}
Pružanjem valjanog skupa podataka:
validate.propertiesMap.first = prop1 validate.propertiesMap.second = prop2 [e-pošta zaštićena]
aplikacija će se normalno pokrenuti i naši će jedinični testovi proći:
@ExtendWith (SpringExtension.class) @EnableConfigurationProperties (value = MailServer.class) @TestPropertySource ("classpath: property-validation-test.properties") javna klasa PropertyValidationUnitTest {@Autowired private MailServer mailServer; privatni statički Validator propertyValidator; @BeforeAll javna statička void postavka () {propertyValidator = Validation.buildDefaultValidatorFactory (). GetValidator (); } @Test void whenBindingPropertiesToValidatedBeans_thenConstrainsAreChecked () {assertEquals (0, propertyValidator.validate (mailServer.getPropertiesMap ()). Size ()); assertEquals (0, propertyValidator.validate (mailServer.getMailConfig ()). size ()); }}
S druge strane, ako koristimo nevaljana svojstva, Spring će izbaciti IllegalStateException pri pokretanju.
Na primjer, pomoću bilo koje od ovih nevažećih konfiguracija:
validate.propertiesMap.second = validate.mail_config.address = user1.test
uzrokovat će neuspjeh naše aplikacije s ovom porukom pogreške:
Svojstvo: validate.propertiesMap [second] Vrijednost: Razlog: ne smije biti prazno Svojstvo: validate.mailConfig.address Vrijednost: user1.test Razlog: mora biti dobro oblikovana adresa e-pošte
Primijeti da koristili smo @Valid na mailConfig polje kako bi se osiguralo da MailConfig ograničenja se provjeravaju, čak i ako validate.mailConfig.address nije definirano. Inače bi proljeće zašlo mailConfig do null i normalno pokrenite aplikaciju.
6. Pretvorba svojstava
Pretvorba svojstava Spring Boot omogućuje nam pretvaranje nekih svojstava u određene tipove.
U ovom ćemo odjeljku započeti s testiranjem klasa konfiguracije koje koriste ugrađenu Spring pretvorbu. Zatim ćemo testirati prilagođeni pretvarač koji sami kreiramo.
6.1. Zadana pretvorba Spring Boota
Razmotrimo sljedeća svojstva veličine i trajanja podataka:
# veličine podataka convert.upload_speed = 500MB convert.download_speed = 10 # trajanja convert.backup_day = 1d convert.backup_hour = 8
Spring Boot će automatski povezati ova svojstva s podudaranjem DataSize i Trajanje polja definirano u PropertyConversion klasa konfiguracije:
@Configuration @ConfigurationProperties (prefix = "convert") javna klasa PropertyConversion {private DataSize uploadSpeed; @DataSizeUnit (DataUnit.GIGABYTES) private DataSize downloadSpeed; privatno trajanje backupDay; @DurationUnit (ChronoUnit.HOURS) privatno trajanje backupHour; // geteri i postavljači}
Sada provjerimo rezultate pretvorbe:
@ExtendWith (SpringExtension.class) @EnableConfigurationProperties (vrijednost = PropertyConversion.class) @ContextConfiguration (klasa = CustomCredentialsConverter.class) @TestPropertySource ( "Classpath: spring-conversion-test.properties") public class SpringPropertiesConversionUnitTest {@Autowired vlastitu PropertyConversion propertyConversion; @Test void whenUsingSpringDefaultSizeConversion_thenDataSizeObjectIsSet () {assertEquals (DataSize.ofMegabytes (500), propertyConversion.getUploadSpeed ()); assertEquals (DataSize.ofGigabytes (10), propertyConversion.getDownloadSpeed ()); } @Test void whenUsingSpringDefaultDurationConversion_thenDurationObjectIsSet () {assertEquals (Duration.ofDays (1), propertyConversion.getBackupDay ()); assertEquals (Duration.ofHours (8), propertyConversion.getBackupHour ()); }}
6.2. Prilagođeni pretvarači
Sada zamislimo da želimo pretvoriti pretvoriti. vjerodajnice svojstvo:
convert.credentials = korisnik, 123
u sljedeće Uvjerenje razred:
vjerodajnice javne klase {privatno korisničko ime niza; privatna lozinka za niz; // geteri i postavljači}
Da bismo to postigli, možemo implementirati prilagođeni pretvarač:
@Component @ConfigurationPropertiesBinding javna klasa CustomCredentialsConverter implementira Converter {@Override public Credentials convert (String source) {String [] data = source.split (","); vratiti nove vjerodajnice (podaci [0], podaci [1]); }}
Na kraju, dodajte a Vjerodajnice polje do PropertyConversion razred:
javna klasa PropertyConversion {vjerodajnice za privatne vjerodajnice; // ...}
U našem SpringPropertiesConversionUnitTest test klasa, također trebamo dodati @ContextConfiguration za registraciju prilagođenog pretvarača u kontekstu Springa:
// ostale napomene @ContextConfiguration (classes = CustomCredentialsConverter.class) javna klasa SpringPropertiesConversionUnitTest {// ... @Test void whenRegisteringCustomCredentialsConverter_thenCredentialsAreParsed () {assertEquals ("user", getCredentials.getgetConversion. assertEquals ("123", propertyConversion.getCredentials (). getPassword ()); }}
Kao što pokazuju prethodne tvrdnje, Spring je koristio naš prilagođeni pretvarač za raščlanjivanje datoteke pretvoriti. vjerodajnice svojstvo u a Vjerodajnice primjer.
7. Obvezivanje YAML dokumenata
Za hijerarhijske podatke o konfiguraciji YAML konfiguracija može biti prikladnija. Uz to, YAML podržava definiranje više profila unutar istog dokumenta.
Sljedeće primjena.iml smješteno pod src / test / resources / definira "test" profil za ServerConfig razred:
spring: profili: testni poslužitelj: adresa: ip: 192.168.0.4 resources_path: imgs: / etc / test / imgs --- # ostali profili
Kao rezultat, proći će sljedeći test:
@ExtendWith (SpringExtension.class) @ContextConfiguration (inicijalizatori = ConfigFileApplicationContextInitializer.class) @EnableConfigurationProperties (value = ServerConfig.class) @ActiveProfiles ("test") public class BindingYmlPropertiesCConfitWonTigProperties @Test void whenBindingYMLConfigFile_thenAllFieldsAreSet () {assertEquals ("192.168.0.4", serverConfig.getAddress (). GetIp ()); // ostale tvrdnje ...}}
Nekoliko napomena u vezi s korištenim bilješkama:
- @ContextConfiguration (inicijalizatori = ConfigFileApplicationContextInitializer.class) - učitava primjena.iml datoteka
- @ActiveProfiles ("test") - određuje da će se tijekom ovog testa koristiti "test" profil
Konačno, imajmo na umu to ni @ProperySource ni @TestProperySource podržati učitavanje .iml datoteke. Stoga bismo uvijek trebali smjestiti naše YAML konfiguracije unutar primjena.iml datoteka.
8. Nadjačavanje @ConfigurationProperties Konfiguracije
Ponekad bismo možda htjeli nadjačati konfiguracijska svojstva koja je učitao @ConfigurationProperties s drugim skupom podataka, posebno tijekom testiranja.
Kao što smo pokazali u prethodnim primjerima, možemo koristiti @TestPropertySource (“path_to_new_data_set”) zamijeniti cijelu izvornu konfiguraciju (pod / src / main / resources) s novom.
Alternativno, mogli bismo selektivno zamijeniti neka izvorna svojstva pomoću Svojstva atribut @TestPropertySource također.
Pretpostavimo da želimo poništiti prethodno definirano validate.mail_config.address svojstvo s drugom vrijednošću. Sve što moramo učiniti je označiti svoj testni razred @TestPropertySource a zatim istom svojstvu dodijelite novu vrijednost putem Svojstva popis:
@TestPropertySource (svojstva = {"[email protected]"})
Slijedom toga, Spring će koristiti novo definiranu vrijednost:
assertEquals ("[zaštićen e-poštom]", mailServer.getMailConfig (). getAddress ());
9. Zaključak
U ovom uputstvu vidjeli smo kako testirati različite vrste klasa konfiguracije koje koriste @ConfigurationProperties napomena za učitavanje .Svojstva i .iml konfiguracijske datoteke.
Kao i obično, izvorni kod za ovaj članak dostupan je na GitHubu.