2016-01-05 10 views
14

La mia applicazione Primavera-Boot-MVC-Web ha la seguente configurazione del database in application.properties di file:Come ricreare il database prima di ogni test in primavera?

spring.datasource.url=jdbc:h2:tcp://localhost/~/pdk 
spring.datasource.username=sa 
spring.datasource.password= 
spring.datasource.driver-class-name=org.h2.Driver 

questa è l'unica configurazione che ho fatto. Nessuna altra configurazione fatta da me da nessuna parte. Tuttavia, Spring e i sottosistemi ricreano automaticamente il database su ogni esecuzione di un'applicazione Web. Il database viene ricreato cioè sul sistema eseguito mentre contiene i dati dopo l'applicazione.

Non stavo capendo questo default e mi aspettavo che questo è adatto per i test.

Ma quando ho iniziato a eseguire i test ho trovato che il database viene ricreato solo una volta. Dato che i test vengono eseguiti senza un ordine predefinito, questo non ha assolutamente senso.

Quindi, la domanda è: come avere senso? Cioè come far ricreare il database prima di ogni test come accade all'avvio dell'applicazione per la prima volta?

Il mio test di intestazione di classe è seguente:

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = myapp.class) 
//@WebAppConfiguration 
@WebIntegrationTest 
@DirtiesContext 
public class WebControllersTest { 

Come vedete, ho provato @DirtiesContext a livello di classe e non ha aiutato.

UPDATE

Ho un fagiolo

@Service 
public class DatabaseService implements InitializingBean { 

che ha un metodo

@Override 
    @Transactional() 
    public void afterPropertiesSet() throws Exception { 
     log.info("Bootstrapping data..."); 
     User user = createRootUser(); 
     if(populateDemo) { 
      populateDemos(); 
     } 
     log.info("...Bootstrapping completed"); 
    } 

Adesso ho fatto è populateDemos() metodo per cancellare tutti i dati dal database. Sfortunatamente, non ha chiamato prima di ogni test nonostante @DirtiesContext. Perché?

+0

Questa è una logica personalizzata. Spring non sa nulla dei tuoi database. Scrivi un '@ Before' e' @ After' per configurare e pulire. –

+0

@SotiriosDelimanolis So che è breve, ma il tuo commento non dovrebbe essere una risposta? –

+0

@JimGarrison Eh, wiki della comunità. –

risposta

27

In realtà, credo che si desidera che questo:

@DirtiesContext(classMode = ClassMode.BEFORE_EACH_TEST_METHOD)

http://docs.spring.io/autorepo/docs/spring-framework/4.2.6.RELEASE/javadoc-api/org/springframework/test/annotation/DirtiesContext.html

@DirtiesContext può essere usato come un livello di classe e metodo livello annotazione all'interno della stessa classe. In tali scenari, il ApplicationContext verrà contrassegnato come dirty dopo qualsiasi metodo annotato e dopo l'intera classe. Se DirtiesContext.ClassMode è impostato su AFTER_EACH_TEST_METHOD, il contesto verrà contrassegnato come dirty dopo ogni metodo di test nella classe.

2

A meno che non si stia utilizzando una sorta di integrazione Spring-Data (che non conosco affatto), sembra una logica personalizzata che è necessario implementare. Spring non conosce i tuoi database, i suoi schemi e le tabelle.

Supponendo JUnit, scrivere i metodi appropriati @Before e @After per configurare e pulire il database, le relative tabelle e i dati. I test possono essi stessi scrivere i dati di cui hanno bisogno e potenzialmente ripulire se stessi, se necessario.

+0

Ma chi cancella il database al momento all'avvio del programma? Se la logica è personalizzata, allora perché sta già cancellando il database senza i miei ordini espliciti? – Dims

+0

È nel database di memoria - non è cancellato, è creato e quindi è vuoto ... – Betlista

+0

Non è nel database di memoria, poiché url è 'dbc: h2: tcp: // localhost/~/pdk'. È un vero database e posso vedere il suo file e accedervi separatamente dagli strumenti del database. Probabilmente è cancellato dalla configurazione di default di Hibernate che è impostata su 'create' o' drop-create'. La domanda è: è possibile kicking reinitalizing non esplicitamente ... – Dims

2

Se si utilizza spring.jpa.hibernate.ddl-auto=create-drop dovrebbe essere sufficiente per creare/eliminare il database?

+0

Questo è probabilmente usato di default da Spring, che non è molto chiaro perché. – Dims

6

Per creare il database che devi fare quello che le altre risposte dicono che con la spring.jpa.hibernate.ddl-auto=create-drop, ora se il vostro intento è quello di pupulate il database su ogni test poi molla fornisce un anotation molto utile

@Transactional(value=JpaConfiguration.TRANSACTION_MANAGER_NAME) 
@Sql(executionPhase=ExecutionPhase.BEFORE_TEST_METHOD,scripts="classpath:/test-sql/group2.sql") 
public class GroupServiceTest extends TimeoffApplicationTests { 

che è da questo pacchetto org.springframework.test.context.jdbc.Sql; ed è possibile eseguire un metodo di test prima e un metodo di test successivo. Per popolare il database.

Per quanto riguarda la creazione del database ogni volta, dici che vuoi solo il test per avere la possibilità di creare-drop è possibile configurare i test con proprietà personalizzate con questa annotazione

@TestPropertySource(locations="classpath:application-test.properties") 
public class TimeoffApplicationTests extends AbstractTransactionalJUnit4SpringContextTests{ 

Speranza che aiuta

Problemi correlati