Zabráňte spusteniu fazule ApplicationRunner alebo CommandLineRunner počas testovania Junit

1. Prehľad

V tomto výučbe si ukážeme, ako môžeme zabrániť fazuli typu ApplicationRunner alebo CommandLineRunner počas testov integrácie Spring Boot.

2. Ukážka aplikácie

Náš príklad aplikácie sa skladá z bežca príkazového riadku, bežca aplikácie a fazule služby úloh.

Bežec príkazového riadku zavolá službu úloh vykonať na vykonanie úlohy pri štarte aplikácie:

@Component verejná trieda CommandLineTaskExecutor implementuje CommandLineRunner {private TaskService taskService; public CommandLineTaskExecutor (TaskService taskService) {this.taskService = taskService; } @Override public void run (String ... args) vyvolá výnimku {taskService.execute ("úloha bežca príkazového riadku"); }} 

Rovnakým spôsobom interaguje bežec aplikácie so službou úloh za účelom vykonania ďalšej úlohy:

@Component public class ApplicationRunnerTaskExecutor implementuje ApplicationRunner {private TaskService taskService; public ApplicationRunnerTaskExecutor (TaskService taskService) {this.taskService = taskService; } @Override public void run (ApplicationArguments args) vyvolá výnimku {taskService.execute ("úloha bežca aplikácie"); }} 

Nakoniec je služba úloh zodpovedná za vykonávanie úloh klienta:

@ Verejná trieda ServiceService TaskService {súkromný statický záznamník Logger = LoggerFactory.getLogger (TaskService.class); public void execute (reťazcová úloha) {logger.info ("do" + úloha); }} 

A máme tiež triedu aplikácií Spring Boot, vďaka ktorej to všetko funguje:

@SpringBootApplication verejná trieda ApplicationCommandLineRunnerApp {public static void main (String [] args) {SpringApplication.run (ApplicationCommandLineRunnerApp.class, args); }}

3. Testovanie očakávaného správania

The ApplicationRunnerTaskExecutor a CommandLineTaskExecutor spustiť po načítaní aplikácie Spring Boot kontext aplikácie.

Môžeme to overiť jednoduchým testom:

@SpringBootTest trieda RunApplicationIntegrationTest {@SpyBean ApplicationRunnerTaskExecutor applicationRunnerTaskExecutor; @SpyBean CommandLineTaskExecutor commandLineTaskExecutor; @Test void whenContextLoads_thenRunnersRun () vyvolá výnimku {verify (applicationRunnerTaskExecutor, times (1)). Run (any ()); verifikovať (commandLineTaskExecutor, times (1)). run (any ()); }}

Ako vidíme, používame SpyBean anotácia pre použitie špiónov Mockito na ApplicationRunnerTaskExecutor a CommandLineTaskExecutor fazuľa. Týmto spôsobom môžeme overiť, či bežať metóda každej z týchto zŕn sa nazývala jedenkrát.

V ďalších častiach sa pozrieme na rôzne spôsoby a techniky, ako zabrániť tomuto predvolenému správaniu počas našich testov integrácie Spring Boot.

4. Prevencia prostredníctvom jarných profilov

Jedným zo spôsobov, ako môžeme zabrániť spusteniu týchto dvoch, je ich anotácia pomocou @Profil:

@Profile ("! Test") @ Verejná trieda komponentov CommandLineTaskExecutor implementuje CommandLineRunner {// rovnako ako predtým}
@Profile ("! Test") @Component - verejná trieda ApplicationRunnerTaskExecutor implementuje ApplicationRunner {// rovnako ako predtým}

Po vyššie uvedených zmenách pokračujeme v našom integračnom teste:

@ActiveProfiles ("test") @SpringBootTest trieda RunApplicationWithTestProfileIntegrationTest {@Autowired súkromný kontext ApplicationContext; @Test void whenContextLoads_thenRunnersAreNotLoaded () {assertNotNull (context.getBean (TaskService.class)); assertThrows (NoSuchBeanDefinitionException.class, () -> context.getBean (CommandLineTaskExecutor.class), „počas tohto integračného testu by sa nemal načítať CommandLineRunner“); assertThrows (NoSuchBeanDefinitionException.class, () -> context.getBean (ApplicationRunnerTaskExecutor.class), „ApplicationRunner by sa nemal načítať počas tohto integračného testu“); }}

Ako vidíme, vyššie uvedenú testovaciu triedu sme anotovali pomocou @ActiveProfiles („test“) anotácia, čo znamená, že nebudú prepojené s anotáciami @Profile („! Test“). Výsledkom je, že ani CommandLineTaskExecutor fazuľa ani ApplicationRunnerTaskExecutor fazuľa je vôbec naložená.

5. Prevencia prostredníctvom ConditionalOnProperty Anotácia

Alebo môžeme nakonfigurovať ich zapojenie podľa vlastnosti a potom použiť ConditionalOnProperty anotácia:

@ConditionalOnProperty (prefix = "application.runner", value = "enabled", havingValue = "true", matchIfMissing = true) @Component verejná trieda ApplicationRunnerTaskExecutor implementuje ApplicationRunner {// rovnako ako predtým} 
@ConditionalOnProperty (prefix = "command.line.runner", value = "enabled", havingValue = "true", matchIfMissing = true) @Component verejná trieda CommandLineTaskExecutor implementuje CommandLineRunner {// rovnako ako predtým}

Ako vidíme, the ApplicationRunnerTaskExecutor a CommandLineTaskExecutor sú predvolene povolené, a môžeme ich deaktivovať, ak nastavíme nasledujúce vlastnosti na nepravdivé:

  • príkaz.line.runner.enabled
  • application.runner.enabled

Takže v našom teste nastavili sme tieto vlastnosti na nepravdivé a ani ApplicationRunnerTaskExecutor ani CommandLineTaskExecutor fazuľa sa načítajú do kontextu aplikácie:

@SpringBootTest (properties = {"command.line.runner.enabled = false", "application.runner.enabled = false"}) trieda RunApplicationWithTestPropertiesIntegrationTest {// rovnako ako predtým}

Teraz, aj keď nám vyššie uvedené techniky pomáhajú dosiahnuť náš cieľ, existujú prípady, keď chceme vyskúšať, či sú všetky jarné fazule naložené a zapojené správne.

Napríklad by sme mohli chcieť otestovať, či TaskService fazuľa sa vstrekuje správne do CommandLineTaskExecutor, ale stále nechceme jeho bežať metóda, ktorá sa má vykonať počas nášho testu. Pozrime sa teda na poslednú časť, ktorá vysvetľuje, ako to môžeme dosiahnuť.

6. Prevencia nespustením celého kontajnera zavedením systému

Tu popíšeme, ako môžeme zabrániť CommandLineTaskExecutor a ApplicationRunnerTaskExecutor fazuľa z vykonania tým, že nespustí celý kontajner aplikácie.

V predchádzajúcich častiach sme použili @SpringBootTest anotácia, čo malo za následok bootstrapovanie celého kontajnera počas našich integračných testov. @SpringBootTest obsahuje dve meta-anotácie, ktoré sú relevantné pre toto posledné riešenie:

@BootstrapWith (SpringBootTestContextBootstrapper.class) @ExtendWith (SpringExtension.class) 

No, ak počas nášho testu nie je potrebné bootstrapovať celý kontajner, nechcete ho používať @BootstrapWith.

Namiesto toho môžeme ho nahradiť @ContextConfiguration:

@ContextConfiguration (classes = {ApplicationCommandLineRunnerApp.class}, initializers = ConfigFileApplicationContextInitializer.class)

S @ContextConfiguration, určujeme, ako načítať a konfigurovať kontext aplikácie pre integračné testy. Nastavením ContextConfiguration triedy majetku, vyhlasujeme, že Spring Boot by mal používať ApplicationCommandLineRunnerApp triedy na načítanie kontextu aplikácie. Definovaním inicializátora ako ConfigFileApplicationContextInitializer, aplikácia načíta svoje vlastnosti.

Stále potrebujeme@ExtendWith (SpringExtension.class) pretože to integruje Spring TestContext Framework do programovacieho modelu Jupitera JUnit 5.

V dôsledku vyššie uvedeného kontext aplikácie Spring Boot načíta komponenty a vlastnosti aplikácie bez vykonania CommandLineTaskExecutor alebo ApplicationRunnerTaskExecutor fazuľa:

@ExtendWith (SpringExtension.class) @ContextConfiguration (classes = {ApplicationCommandLineRunnerApp.class}, initializers = ConfigFileApplicationContextInitializer.class) verejná trieda LoadSpringContextIntegrationTest {@SpyBean TaskService taskService; @SpyBean CommandLineRunner commandLineRunner; @SpyBean ApplicationRunner applicationRunner; @Test void whenContextLoads_thenRunnersDoNotRun () vyvolá výnimku {assertNotNull (taskService); assertNotNull (commandLineRunner); assertNotNull (applicationRunner); verifikácia (taskService, times (0)). execute (any ()); verifikácia (commandLineRunner, times (0)). run (any ()); overiť (applicationRunner, times (0)). run (any ()); }} 

Musíme si to tiež uvedomiť the ConfigFileApplicationContextInitializer, ak sa používa samostatne, neposkytuje podporu pre @Value („$ {…}“) injekcia. Ak to chceme podporiť, musíme nakonfigurovať a PropertySourcesPlaceholderConfigurer.

7. Záver

V tomto článku sme si ukázali rôzne spôsoby, ako zabrániť vykonaniu ApplicationRunner a CommandLineRunner fazuľa počas testov integrácie Spring Boot.

Ako vždy, kód je k dispozícii na GitHub.


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