2015-03-30 10 views
22
@RunWith(SpringJUnit4ClassRunner.class) 
public void ITest { 
    @Autowired 
    private EntityRepository dao; 

    @BeforeClass 
    public static void init() { 
     dao.save(initialEntity); //not possible as field is not static 
    } 
} 

Come posso avere il mio servizio iniettato già nella classe init statica?Come eseguire il campo autowire in static @BeforeClass?

+3

Questo post del blog può aiutare - http: //saltnlight5.blogspot .in/2012/09/enhancing-spring-test-framework-with.html – Mithun

risposta

7

Mi sembra che si stia tentando di popolare DB prima dei test.

darei una prova per due opzioni:

  • Se è possibile estrarre gli script iniziali a file SQL (se questo è un'opzione per voi senza usare fagioli repository) è possibile utilizzare this approach e annotare il test con @Sql
  • È possibile esplorare DbUnit e qui è link to spring dbunit connector che sta facendo esattamente questo e ti aiuta a popolare DB prima dei test. Ecco un github link per l'integrazione tra framework di test a molla e dbunit. Dopo averlo fatto di avere @DatabaseSetup e @DatabaseTearDown che farà cosa sul DB è necessario

So che questo non risponde come iniettare fagiolo in statica @BeforeClass ma il codice modulo ha l'aspetto si sta risolvendo il problema.

Aggiornamento: Recentemente ho incontrato lo stesso problema nel mio progetto e tirato fuori this article che mi ha aiutato e penso che è elegante modo di affrontare questo tipo di problema. È possibile estendere SpringJUnit4ClassRunner con listener che può eseguire l'installazione a livello di istanza con tutti i bean definiti.

2

Per rispondere a questa domanda dobbiamo ricapitolare le versioni Spring 2.x.

Se si desidera "autowire" un bean nella classe @BeforeTest, è possibile utilizzare l'interfaccia ApplicationContext. Vediamo un esempio:

@BeforeClass 
    public static void init() { 
     ApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml"); 
     EntityRepository dao2 = (EntityRepository) context.getBean("dao"); 
     List<EntityRepository> all = dao2.getAll(); 
     Assert.assertNotNull(all); 
    } 

Cosa sta succedendo: utilizzando il ClassPathXmlApplicationContext stiamo istanziare tutti i fagioli contenuti nel file application-context.xml.

Con context.getBean() si legge il bean specificato (deve corrispondere al nome del bean!); e quindi puoi usarlo per la tua inizializzazione.

Si dovrebbe dare al bean un altro nome (questo è il dao2!) Altrimenti Spring normale "autowired" non può funzionare sul bean predefinito.

Come nota a margine, se il test estende AbstractTransactionalJUnit4SpringContextTests, è possibile eseguire l'inizializzazione utilizzando executeSqlScript(sqlResourcePath, continueOnError); metodo, in modo da non dipendere da una classe/metodo che devi anche testare separatamente.

+0

Non riesco a creare l'istanza di 'ApplicationContext' perché anch'io utilizzo' @ IntegrationTest' per rendere autowire le normali classi '@ EnableAutoConfiguration' durante il test (configurazione basata su annotazione). – membersound

+0

Perché non usi 'executeSqlScript' allora?È un metodo statico che si ottiene gratuitamente quando si estende la classe 'AbstractTransactionalJUnit4SpringContextTests'. – musikele

+0

La domanda è ovviamente solo un esempio. Potrei anche dover eseguire qualsiasi logica in @BeforeClass, non solo l'inizializzazione del database ... – membersound

9

Una soluzione che ho utilizzato per ottenere questo lavoro è quello di utilizzare @Before con una bandiera di saltarlo in corso di esecuzione per ogni testcase

@RunWith(SpringJUnit4ClassRunner.class) 
public class BaseTest { 

@Autowired 
private Service1 service1; 

@Autowired 
private Service2 service2; 

private static boolean dataLoaded = false; 

@Before 
public void setUp() throws Exception { 

    if (!dataLoaded) { 
     service1.something(); 
     service2.somethingElse(); 
     dataLoaded = true; 
    } 
    } 
} 
+2

Continuo a farlo, ma ci deve essere un modo migliore, soprattutto, quando ci si affida a un campo injected/autowired, perché in questo caso '@ BeforeClass' non funzionerà. – carlspring

+0

E la parte @AfterClass dopo l'esecuzione dei test. Qualche strategia per mantenerla semplice come questa prima parte? – emecas

Problemi correlati