2013-10-18 15 views
5

Ho un bean Spring 3.2.4 statico con un metodo @PostConstruct protetto che carica i dati da un DB durante l'inizializzazione.Come posticipare la chiamata @PostConstruct fino a quando jUnit ha impostato il contesto di test

Quando si crea un test jUnit, nei miei metodi di test, desidero impostare i dati nel DB per testare correttamente il bean. Tuttavia, dato che il bean viene istanziato prima dei miei metodi di test, non so come richiedere a Spring di posticipare l'istanza del bean fino a quando il metodo non è completo.

Dato che il metodo @PostConstruct è protetto, non posso richiamarlo direttamente per reinizializzare il bean, a meno che non utilizzi il reflection.

C'è un altro modo per farlo, o il riflesso è l'unico modo? Spring ha delle classi Util per renderlo più semplice o devo usare il java reflection standard?

risposta

2

È sempre possibile avviare il contesto a livello di programmazione per tale caso d'uso. Tieni presente che in questo caso sei responsabile del ciclo di vita del contesto. Il seguente pseudo-codice illustra questo:

@Test 
public void yourTest() { 
    // setup your database 

    ConfigurableApplicationContext context = 
     new ClassPathXmlApplicationContext("/org/foo/your-context.xml"); 
    // Or new AnnotationConfigApplicationContext(YourConfig.class) 
    try { 
     YourBean bean = context.getBean("beanId"); 
     // Assertions 
    } finally { 
     context.close(); 
    } 
} 

Probabilmente è necessario Spring per inizializzare il database. Ad esempio, è possibile utilizzare il normale supporto al contesto di test di Spring per inizializzare solo i bean necessari per l'installazione del database e avviare un altro contesto al livello di programmazione per far valere il proprio servizio. Se tale contesto ha bisogno di alcuni servizi che sono stati utilizzati per l'inizializzazione del database, è possibile avviare un contesto di bambino, invece, qualcosa di simile a

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration // for instance FooTest-context.xml 
public class FooTest { 

    @Autowired 
    private ApplicationContext mainContext; 

    @Test 
    public void yourTest() { 
     // setup your database 

     ClassPathXmlApplicationContext context = 
       new ClassPathXmlApplicationContext(); 
     context.setParent(mainContext); 
     context.setConfigLocation("/org/foo/your-context.xml"); 
     context.refresh(); 
     try { 
      YourBean bean = context.getBean("beanId"); 
      // Assertions 
     } finally { 
      context.close(); 
     } 
    } 
} 

Se che sta diventando un caso d'uso ricorrente è possibile creare un metodo di modello che inizia il contenitore e invocare un'interfaccia di callback. In questo modo è possibile condividere la gestione del ciclo di vita del contesto in un punto centrale.

+0

Grazie. Ho finito per aggirare il problema, ma la tua soluzione mi dà sicuramente un altro modo di guardarlo. –

Problemi correlati