2015-03-12 23 views
20

Quando eseguo i miei test di unità, richiama le mie attività pianificate. Voglio evitare questo comportamento, che è causato dal fatto che ho @EnableScheduling sulla mia configurazione dell'app principale.Disabilita @EnableScheduling su Spring Test

Come posso disabilitare questo test?

Mi sono imbattuto in questo question/answer che suggerisce di impostare i profili?

Non sai come andrei a riguardo? o se è eccessivo? Stavo pensando di avere una AppConfiguration separata per i miei test unitari ma mi sembra di ripetere due volte il codice quando lo faccio?

@Configuration 
@EnableJpaRepositories(AppConfiguration.DAO_PACKAGE) 
@EnableTransactionManagement 
@EnableScheduling 
@ComponentScan({AppConfiguration.SERVICE_PACKAGE, 
       AppConfiguration.DAO_PACKAGE, 
       AppConfiguration.CLIENT_PACKAGE, 
       AppConfiguration.SCHEDULE_PACKAGE}) 
public class AppConfiguration { 

    static final String MAIN_PACKAGE    = "com.etc.app-name"; 
    static final String DAO_PACKAGE    = "com.etc.app-name.dao"; 
    private static final String ENTITIES_PACKAGE = "com.etc.app-name.entity"; 
    static final String SERVICE_PACKAGE   = "com.etc.app-name.service"; 
    static final String CLIENT_PACKAGE   = "com.etc.app-name.client"; 
    static final String SCHEDULE_PACKAGE   = "com.etc.app-name.scheduling"; 


    @Bean 
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(){ 
     // stripped code for question readability 
    } 

    // more app config code below etc 

} 

Esempio di test unità.

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes={AppConfiguration.class}) 
@Transactional 
@TransactionConfiguration(defaultRollback = true) 
@WebAppConfiguration 
public class ExampleDaoTest { 

    @Autowired 
    ExampleDao exampleDao; 

    @Test 
    public void testExampleDao() { 
     List<Example> items = exampleDao.findAll(); 
     Assert.assertTrue(items.size()>0); 
    } 
} 
+0

Perché si vuole utilizzare contesto molla per test di unità? –

+0

così autowires i miei oggetti in modo da poter testare i miei dao e servizi? –

+0

Si potrebbe solo deridere il Dao. Il migliore sarebbe usare qualche framework come Mockito. –

risposta

16

Se non si desidera utilizzare i profili, è possibile aggiungere un flag che abiliti/disabiliti la pianificazione per il applicazione

Nel tuo AppConfiguration aggiungi questo

@ConditionalOnProperty(
    value = "app.scheduling.enable", havingValue = "true", matchIfMissing = true 
) 
    @Configuration 
    @EnableScheduling 
    public static class SchedulingConfiguration { 
    } 

e il test è sufficiente aggiungere questa annotazione per disabilitare la pianificazione

@TestPropertySource(properties = "app.scheduling.enable=false") 
+1

in qualche modo ha ucciso le mie configurazioni di avvio a molla – Hinotori

+1

Si noti che i componenti esterni potrebbero abilitare la pianificazione automaticamente (vedere HystrixStreamAutoConfiguration e MetricExportAutoConfiguration da Spring Framework). Quindi, se provi e usi '@ ConditionalOnProperty' o' @ Profile' nella classe '@ Configuration' che specifica' @ EnableScheduling', la programmazione sarà comunque abilitata a causa di componenti esterni. vedere https://stackoverflow.com/a/46783392/2947239 – Sisyphus

+0

Sisyphus fa lo stesso punto che stavo per fare. Vorrei aggiungere che MetricExportAutoConfiguration proviene da Spring Boot Actuator e può essere disabilitato in un profilo di prova con: spring.metrics.export.enabled: false –

2

in ciascuna prova si definisce quale configurazione primavera dovrebbe essere utilizzato, attualmente si dispone di:

@ContextConfiguration(classes={AppConfiguration.class}) 

pratica comune è quello di definire la configurazione a molla separata per la vostra applicazione normale e per i test.

AppConfiguration.java 
TestConfiguration.java 

Poi, nel tuo test è sufficiente refference TestConfiguration al posto del tuo attuale AppConfiguration utilizzando @ContextConfiguration(classes={TestConfiguration.class})

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes={TestConfiguration.class}) 
@Transactional 
@TransactionConfiguration(defaultRollback = true) 
@WebAppConfiguration 
public class ExampleDaoTest 

In questo modo è possibile configurare qualsiasi impostazione per i test in modo diverso rispetto nel codice di produzione. Ad esempio, è possibile utilizzare il database in memoria per i test anziché uno normale e molto altro.

+3

Sfortunatamente non funziona in questo modo. Il test utilizza la classe TestConfiguration ma utilizza anche le annotazioni dichiarate su TestConfiguration.:( – ali

+0

È possibile impostare una classe di configurazione di test o un profilo attivo da prelevare dal file delle proprietà, tuttavia, facendo ciò, non si evita la programmazione della classe annotata. –

+1

http://stackoverflow.com/questions/40226937/metodo-pianificato-è-chiamato-durante-i-test -Questo ha funzionato per me –

4

Un'alternativa sarebbe annullare la registrazione del post processor del bean che pianifica gli eventi. Questo può essere fatto semplicemente mettendo la seguente classe nel classpath dei vostri test:

public class UnregisterScheduledProcessor implements BeanFactoryPostProcessor { 

    @Override 
    public void postProcessBeanFactory(final ConfigurableListableBeanFactory beanFactory) throws BeansException { 
     for (String beanName : beanFactory.getBeanNamesForType(ScheduledAnnotationBeanPostProcessor.class)) { 
      ((DefaultListableBeanFactory)beanFactory).removeBeanDefinition(beanName); 
     } 
    } 
} 

Mentre questo è abbastanza semplice e sembra fare il lavoro, fate attenzione che non ho la prova questa molto o verificare la presenza di possibili implicazioni di rimuovere un bean definito dal registro o assicurarsi che l'ordine di PostProcessors non sia un problema ...

+1

Solo per dare un feedback - Ho appena provato questo metodo e sembra funzionare bene. – RockMeetHardplace

+0

Ho provato @ vojtech-ruzicka e @ risposte lolotron più altre risposte su [questa domanda simile qui] (https://stackoverflow.com/questions/40226937/scheduled-method-is-called-during-the-tests) Allo stesso modo devo aggiungere che solo @yankee risposta ha funzionato per me. Con un'annotazione '@ Configuration' sul suo esempio' UnregisterScheduledProcessor' class per essere caricato automaticamente da Spring sotto il mio test. Finora non ho xperience eventuali problemi con esso. – DaddyMoe