2013-11-26 22 views
5

consideri il tipico DBUnit Primavera di prova (vedi https://github.com/springtestdbunit/spring-test-dbunit):Come fare in modo che DBUnit @DatabaseSetup si verifichi prima dell'autowiring della primavera?

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { 
"classpath:/META-INF/spring/applicationContext-database.xml", 
"classpath:spring-*.xml" 
}) 
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, 
    DirtiesContextTestExecutionListener.class, 
    TransactionalTestExecutionListener.class, 
    DbUnitTestExecutionListener.class }) 
@DatabaseSetup("/dbunit/data.xml") 
public class UnitTest { 

    @Autowired 
    private UnitUnderTest uut; 

    @Test 
    public void shouldInitDB() { 
     ... 
    } 
} 

Quello che ho verificato è che, e ha previsto, autowiring avverrà prima DatabaseSetup. Ciò deve accadere perché DBUnit dipende dal contesto dell'applicazione per fornire l'origine dati configurata.

Il problema è che il bean UnitUnderTest ha un @PostConstruct in cui carica alcuni dati dal DB ma, poiché l'Autowiring avviene prima dell'impostazione di DBunit, i dati non saranno disponibili in questa fase.

Qualche idea su come risolvere questo problema in modo pulito?

+1

Stesso problema qui. Qualche soluzione? – Puce

+0

Non è davvero una buona soluzione, ma mi ha permesso di andare avanti.Crea un TestClass che eredita dall'oggetto da autowired ed espone un metodo per l'inizializzazione esterna. Utilizzare nel test @Before. –

+0

Nessuna soluzione fino ad ora. Nemmeno una soluzione decente. Continuerà a cercare. –

risposta

0

È possibile avere un metodo di installazione nella classe di test e chiamare manualmente il metodo di costruzione post. Funzionerà.

+0

Ho paura che non sia una soluzione! In tal caso dovrei passare la responsabilità di chiamare quel metodo ad un altro bean. Non penso che ci sia bisogno di farlo. Sto saltando il test di primavera-dbunit avrà un modo più pulito, meno invadente di testare questo tipo di scenario, che sono sicuro non sarà così raro. –

+0

Il mio metodo postconstruct tenta di recuperare l'oggetto del database e si interrompe durante l'autowiring, quindi questa soluzione non sarà di aiuto. – TheBakker

1

Puoi trovare Spring's ResourceDatabasePopulator.

penso che si può usare qualcosa di simile

@PostConstruct 
public void myInMemryPopulator() { 
final ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(); 

     try { 

      Resource[] array = resourceResolver.getResources("classpath:/*.sql");  

      for (Resource resource : array) { 

       databasePopulator.addScript(resource); 
      } 
      databasePopulator.populate(dataSource.getConnection()); 

     } catch (IOException | SQLException e) { 
      LOGGER.error("Error in databasePopulator {} ", e); 
     } 

    } 
+0

se ancora non aiuta. È possibile creare il caso di test genitore e aggiungere il blocco statico nel caso di test genitore può chiamare questo metodo – Niraj