Akadályozza meg az ApplicationRunner vagy a CommandLineRunner bab végrehajtását a Junit tesztelés során

1. Áttekintés

Ebben az oktatóanyagban megmutatjuk, hogyan előzhetjük meg az ilyen típusú babot ApplicationRunner vagy CommandLineRunner a futást a Spring Boot integrációs tesztek alatt.

2. Példa alkalmazásra

Példapéldánk egy parancssori futóból, egy alkalmazás futóból és egy feladat-kiszolgáló babból áll.

A parancssori futó felhívja a feladatszolgáltatást végrehajtani módszer, egy feladat végrehajtásához az alkalmazás indításakor:

@Component public class A CommandLineTaskExecutor végrehajtja a CommandLineRunner {private TaskService taskService; public CommandLineTaskExecutor (TaskService taskService) {this.taskService = taskService; } @Orride public void run (String ... args) dobja a Exception {taskService.execute ("parancssori futó feladat") kivételt; }} 

Ugyanígy az alkalmazásfuttató interakcióba lép a feladatszolgáltatással egy másik feladat végrehajtása érdekében:

@Component public class ApplicationRunnerTaskExecutor implementálja az ApplicationRunner {private TaskService taskService; public ApplicationRunnerTaskExecutor (TaskService taskService) {this.taskService = taskService; } @Orride public void run (ApplicationArguments args) dobja a Exception {taskService.execute ("alkalmazás futó feladat") kivételt; }} 

Végül, a feladatszolgáltatás felelős az ügyfél feladatai végrehajtásáért:

@Service public class TaskService {private static Logger logger = LoggerFactory.getLogger (TaskService.class); public void execute (String task) {logger.info ("do" + task); }} 

És van egy Spring Boot alkalmazásosztályunk is, amely mindezt működőképessé teszi:

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

3. A várható viselkedés tesztelése

A ApplicationRunnerTaskExecutor és a CommandLineTaskExecutor futtatás után a Spring Boot betölti az alkalmazás környezetét.

Ezt egy egyszerű teszt segítségével ellenőrizhetjük:

@SpringBootTest osztály RunApplicationIntegrationTest {@SpyBean ApplicationRunnerTaskExecutor applicationRunnerTaskExecutor; @SpyBean CommandLineTaskExecutor commandLineTaskExecutor; @Test void whenContextLoads_thenRunnersRun () dobja a Kivételt {verify (applicationRunnerTaskExecutor, times (1)). ellenőrizze (commandLineTaskExecutor, times (1)). run (any ()); }}

Mint látjuk, a SpyBean kommentár a Mockito kémek alkalmazásához a ApplicationRunnerTaskExecutor és CommandLineTaskExecutor bab. Ezzel ellenőrizhetjük, hogy a fuss módszerét ezeknek a baboknak egyszer hívták.

A következő szakaszokban különféle módszereket és technikákat fogunk megismerni ennek az alapértelmezett viselkedésnek a megakadályozására a Spring Boot integrációs tesztjeink során.

4. Megelőzés tavaszi profilokon keresztül

Az egyik módja annak, hogy megakadályozzuk ennek a kettőnek a futását, az, ha annotáljuk őket @Profil:

@Profile ("! Test") @Component public class A CommandLineTaskExecutor végrehajtja a CommandLineRunner {// ugyanazokat, mint korábban}
@Profile ("! Test") @Component public class ApplicationRunnerTaskExecutor implementálja az ApplicationRunner {// -ot, mint korábban}

A fenti változtatások után folytatjuk az integrációs tesztet:

@ActiveProfiles ("teszt") @SpringBootTest osztály RunApplicationWithTestProfileIntegrationTest {@Autowired private ApplicationContext kontextus; @Test void whenContextLoads_thenRunnersAreNotLoaded () {assertNotNull (context.getBean (TaskService.class)); assertThrows (NoSuchBeanDefinitionException.class, () -> context.getBean (CommandLineTaskExecutor.class), "A CommandLineRunner programot nem szabad betölteni az integrációs teszt során"); assertThrows (NoSuchBeanDefinitionException.class, () -> context.getBean (ApplicationRunnerTaskExecutor.class), "Az ApplicationRunnert nem szabad betölteni az integrációs teszt során"); }}

Ahogy látjuk, a fenti tesztosztályt a @ActiveProfiles („teszt”) annotáció, ami azt jelenti, hogy nem fogja bekötni azokat, amelyekkel annotáltak @Profile (“! Teszt”). Ennek eredményeként sem a CommandLineTaskExecutor bab, sem a ApplicationRunnerTaskExecutor bab egyáltalán van terhelve.

5. Megelőzés a ConditionalOnProperty Megjegyzés

Vagy konfigurálhatjuk vezetékeiket tulajdonságok szerint, majd használhatjuk a ConditionalOnProperty kommentár:

@ConditionalOnProperty (előtag = "application.runner", value = "engedélyezve", havingValue = "true", matchIfMissing = true) @Component public class 
@ConditionalOnProperty (előtag = "command.line.runner", érték = "engedélyezve", havingValue = "true", matchIfMissing = true)

Ahogy látjuk, a ApplicationRunnerTaskExecutor és a CommandLineTaskExecutor alapértelmezés szerint engedélyezve vannak, és letilthatjuk őket, ha a következő tulajdonságokat állítjuk be hamis:

  • command.line.runner.enabled
  • application.runner.enabled

Tehát a tesztünk során ezeket a tulajdonságokat arra állítottuk hamis és sem a ApplicationRunnerTaskExecutor sem a CommandLineTaskExecutor a bab kerül az alkalmazás kontextusába:

@SpringBootTest (tulajdonságok = {"command.line.runner.enabled = false", "application.runner.enabled = false"}) osztály RunApplicationWithTestPropertiesIntegrationTest {// ugyanaz, mint korábban}

Most, bár a fenti technikák segítenek a célunk elérésében, vannak esetek, amikor azt akarjuk tesztelni, hogy az összes tavaszi bab megfelelően van-e betöltve és bekötve.

Például tesztelhetjük, hogy a TaskService babot helyesen adják be a CommandLineTaskExecutor, de még mindig nem akarjuk fuss tesztünk során végrehajtandó módszer. Tehát nézzük meg az utolsó részt, amely elmagyarázza, hogyan érhetjük el ezt.

6. Megelőzés a teljes konténer nem indításával

Itt leírjuk, hogyan előzhetjük meg a CommandLineTaskExecutor és ApplicationRunnerTaskExecutor babot a végrehajtásból, mivel nem indítja el a teljes alkalmazástárolót.

Az előző szakaszokban a @SpringBootTest megjegyzéssel, és ez azt eredményezte, hogy az egész tároló bootstrapelésre került az integrációs tesztjeink során. @SpringBootTest két meta-annotációt tartalmaz, amelyek relevánsak az utolsó megoldás szempontjából:

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

Nos, ha a tesztünk során nem kell indítanunk a teljes tárolót, akkor ne akarjuk használni @BootstrapWith.

Helyette, helyettesíthetjük azzal @ContextConfiguration:

@ContextConfiguration (class = {ApplicationCommandLineRunnerApp.class}, inicializátorok = ConfigFileApplicationContextInitializer.class)

Val vel @ContextConfiguration, meghatározzuk az alkalmazás kontextusának betöltését és konfigurálását az integrációs tesztekhez. A ContextConfiguration osztályok tulajdonság, kijelentjük, hogy a Spring Boot-nak a ApplicationCommandLineRunnerApp osztály az alkalmazás kontextusának betöltéséhez. Az inicializáló definiálásával ConfigFileApplicationContextInitializer, az alkalmazás betölti tulajdonságait.

Még mindig szükségünk van@ExtendWith (SpringExtension.class) mivel ez a Spring TestContext keretrendszert integrálja a JUnit 5 Jupiter programozási modelljébe.

A fentiek eredményeként a Spring Boot alkalmazáskörnyezet az alkalmazás végrehajtása nélkül tölti be az alkalmazás összetevőit és tulajdonságait CommandLineTaskExecutor vagy a ApplicationRunnerTaskExecutor bab:

@ExtendWith (SpringExtension.class) @ContextConfiguration (class = {ApplicationCommandLineRunnerApp.class}, inicializátorok = ConfigFileApplicationContextInitializer.class) public class LoadSpringContextIntegrationTest {@SpyBean TaskService taskService; @SpyBean CommandLineRunner commandLineRunner; @SpyBean ApplicationRunner applicationRunner; @Test void whenContextLoads_thenRunnersDoNotRun () Exception {assertNotNull (taskService); assertNotNull (commandLineRunner); assertNotNull (applicationRunner); verify (taskService, times (0)). execute (any ()); ellenőrizze (commandLineRunner, times (0)). run (any ()); ellenőrizze (applicationRunner, times (0)). run (any ()); }} 

Ezt is szem előtt kell tartanunk a ConfigFileApplicationContextInitializer, ha önmagában használják, nem nyújt támogatást @Value („$ {…}”) injekció. Ha támogatni akarjuk, akkor be kell állítanunk a PropertySourcesPlaceholderConfigurer.

7. Következtetés

Ebben a cikkben számos módszert mutattunk be a ApplicationRunner és CommandLineRunner bab a Spring Boot integrációs tesztek során.

Mint mindig, a kód elérhető a GitHubon.