2015-03-30 20 views
20

Jeśli w swojej klasie TestCase jest to adnotacje:zajęcia uniemożliwiają zastosowanie/CommandLineRunner z wykonaniem podczas testów JUnit

@SpringApplicationConfiguration(classes = {Application.class}) 

to spowoduje Application.class, wdrożenie interfejsu CommandLineRunner, aby uruchomić wymaganej metody

public void run(String... args) throws Exception 

Nadal uważam, że jest to najczęściej niepożądane zachowanie, ponieważ w środowisku testowym może nie być konieczne uruchomienie całej aplikacji.

mam na myśli dwa rozwiązania, aby obejść ten problem:

  1. do usuwania interfejs CommandLineRunner z mojego Application klasy
  2. mieć inny kontekst testowania

Zarówno To rozwiązanie wymaga dużo kodowania. Czy masz wygodniejsze rozwiązanie?

+2

Czy możesz podać przykład co chcesz przetestować? Jeśli chcesz przetestować coś bez całej aplikacji, to nie potrzebujesz adnotacji. – alexvetter

+2

Chciałbym przetestować całą aplikację (powiedzmy ze wszystkimi zarejestrowanymi ziarnami). Nie podoba mi się to, że zaczyna się cała aplikacja, ze względu na implementację interfejsu 'CommandLineRunner'. Powinien istnieć sposób na załadowanie takiej klasy aplikacji bez uruchamiania metody 'run'. – Gorgia666

+0

To jest dokładnie moja opinia, jest to niechciany efekt uboczny lub przynajmniej SpringRunner powinien dać opcję, aby temu zapobiec. i uruchom kontekst, gdy wszystko w teście jest ustawione. – mohamnag

Odpowiedz

0

Rozwiązuję to, nie wdrażając CommandLineRunner. Po prostu pobierz komponent z kontekstu i wywołaj metodę, przekazując argv. W ten sposób uzyskasz ten sam wynik, a aplikacja nie uruchomi się automatycznie po uruchomieniu testów.

11

Możesz zdefiniować konfigurację testu w tym samym pakiecie co twoja aplikacja, która wygląda dokładnie tak samo, z tym wyjątkiem, że wyklucza komponenty bean implementujące CommandLineRunner. Kluczem jest tu @ ComponentScan.excludeFilters:

@Configuration 
@ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = CommandLineRunner.class)) 
@EnableAutoConfiguration 
public class TestApplicationConfiguration { 
} 

Następnie wystarczy zastąpić konfigurację na teście:

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringBootTest(classes = TestApplicationConfiguration.class) 
public class SomeApplicationTest { 
    ... 
} 

Nie CommandLineRunner zostanie wykonany teraz, ponieważ nie są one częścią konfiguracji.

+2

Ta odpowiedź jest bardzo sprytna, po prostu pomija jeden bit: musisz również wykluczyć 'Application.class' z atrybutu' excludeFilters', lub zeskanuje komponenty, które próbowałeś wykluczyć. –

+1

'SpringApplicationConfiguration' @deprecated od wersji 1.4 na rzecz' SpringBootTest'. Można go zastąpić przez '@SprinBootTest (classes = TestApplicationConfiguration.class)' – Gangaraju

0

Poprzednie odpowiedzi mnie nie zadziałały. Skończyło się na używaniu różnych profili - przykład metody init w Spring Boot:

SpringApplication app = new SpringApplication(AppConfig.class); 
app.setAdditionalProfiles("production"); 
app.run(args); 

To nie jest wykonywane podczas testów, więc jesteśmy tu bezpieczni.

Wszystkie testy mają swój własny profil „test” (co jest przydatne w wielu innych sposobów, zbyt):

@RunWith(SpringJUnit4ClassRunner.class) 
@ActiveProfiles("test") 
public class MyFancyTest {} 

linii poleceń biegacz jest opatrzone „produkcji” profilu więc testy zignorować :

@Component 
@Profile("production") 
public class JobCommandLineRunner implements CommandLineRunner {} 
18

Rozwiązanie Jana można łatwiej osiągnąć.

w klasie testowej, aktywuj "test" profil:

@RunWith(SpringJUnit4ClassRunner.class) 
@ActiveProfiles("test") 
public class MyFancyTest {} 

w twojej CommandLineRunner ustawić profil NIE Test:

@Component 
@Profile("!test") 
public class JobCommandLineRunner implements CommandLineRunner {} 

Wtedy nie trzeba ręcznie ustawić profil w aplikacji.

+0

To działało dobrze dla mnie! Dzięki –

5

Jak wspomniano w dokumentacji wiosennej http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html można użyć @ContextConfiguration ze szczególnym inicjatora:

ConfigFileApplicationContextInitializer jest ApplicationContextInitializer, które mogą mieć zastosowanie do badań, aby załadować Wiosna Boot application.properties Pliki. Możesz użyć tego, gdy nie potrzebujesz wszystkich funkcji dostępnych pod @SpringApplicationConfiguration.

W tym przykładzie anyComponent jest inicjowany i właściwości są wstrzykiwane lecz run (arg) metody nie będzie wykonywane. (Application.class jest moim głównym punktem wejścia wiosna)

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes = Application.class, 
         initializers = ConfigFileApplicationContextInitializer.class) 
public class ExtractorTest { 
    @Autowired 
    AnyComponent anyComponent; 

    @Test 
    public void testAnyComponent() { 
     anyComponent.anyMethod(anyArgument); 
    } 
} 
+0

Pracował jak urok! Dziękujemy @jmgonet –

+0

Dobry przykład !, Nie ma potrzeby dodawania kodu. ex) @Profile .. – traeper

5

Jestem trochę późno do partii, ale rozsądne podejście jest, aby zaznaczyć Bean z @ConditionalOnProperty, np

@ConditionalOnProperty(prefix = "job.autorun", name = "enabled", havingValue = "true", matchIfMissing = true) 
public CommandLineRunner myRunner() {...} 

Poniższa adnotacja będzie następnie wyłącz je w testach:

@SpringBootTest(properties = {"job.autorun.enabled=false"}) 
+0

Jest to najlepsze rozwiązanie, gdy nadal trzeba korzystać z adnotacji na głównej klasie, aby skonfigurować aplikację przed testem, ale należy unikać uruchamiania określonego komponentu bean. Idealny dla aplikacji wiersza poleceń, która ma "wszystko" uruchamiające się. Dzięki. –

Powiązane problemy