2014-11-25 8 views
9

Sto cercando di coniugare le annotazioni di seguire:Come eseguire @sql prima di un metodo @Before

org.springframework.test.context.jdbc.Sql e org.junit.Before

Come il codice seguente:

@Test 
@Sql(scripts = "dml-parametro.sql") 
public void testData(){ 
    Iterable<Parametro> parametros = parametroService.findAll(); 
    List<Parametro> parametrosList = Lists.newArrayList(parametros); 

    Assert.assertThat(parametrosList.size(), Is.is(1)); 
} 

@Before 
public void beforeMethod() { 
    JdbcTestUtils.deleteFromTables(jdbcTemplate, "PARAMETRO"); 
} 

il codice nel metodo @Before è in funzione dopo lo script "DML-parametro.sql" nel l'annotazione @sql.

È giusto fare questo?

Per la soluzione, sto utilizzando @After al posto di @Before, ma vorrei eliminare le tabelle prima dell'esecuzione del test, non dopo.

Non vorrei usare @SqlConfig. Non utilizzo lo scope transazionale a livello di test, quindi ho bisogno di pulire i miei tavoli in ogni metodo di prova. Se ogni metodo di test ha bisogno di pulire le tabelle, vorrei farlo nel metodo @Before. Non vorrei farlo in ogni metodo di prova con @SqlConfig. Penso che il comportamento di @Sql da eseguire prima di @Before sia sbagliato.

risposta

31

Per impostazione predefinita, tutti gli script SQL eseguiti tramite @Sql saranno eseguite prima qualsiasi @Before metodi. Pertanto, il comportamento che si verifica è corretto, ma è possibile modificare la fase di esecuzione tramite l'attributo executionPhase in @Sql (vedere l'esempio di seguito).

Se si desidera eseguire più script, ciò è possibile anche tramite @Sql.

Quindi, se si dispone di uno script clean-up di nome clean-parametro.sql che elimina dalla tabella PARAMETRO, si potrebbe annotare il metodo di prova nel modo seguente (invece di invocare JdbcTestUtils.deleteFromTables() nel metodo @Before).

@Test 
@Sql({"dml-parametro.sql", "clean-parametro.sql"}) 
public void test() { /* ... */ } 

Naturalmente, se dml-parametro.sql inserti valori nella tabella PARAMETRO, allora probabilmente non ha senso eliminare immediatamente questi valori nello script clean-up.

Si prega di notare che @Sql e @SqlConfig forniscono più livelli di configurazione per l'esecuzione dello script.

Ad esempio, se si desidera creare le tabelle prima del test e ripulire dopo il test, si potrebbe fare qualcosa di simile a Java 8:

@Test 
@Sql("create-tables.sql") 
@Sql(scripts = "clean-up.sql", executionPhase = AFTER_TEST_METHOD) 
public void test() { /* ... */ } 

Oppure utilizzare @SqlGroup come un contenitore su Java 6 o Java 7:

@Test 
@SqlGroup({ 
    @Sql("create-tables.sql"), 
    @Sql(scripts = "clean-up.sql", executionPhase = AFTER_TEST_METHOD) 
}) 
public void test() { /* ... */ } 

Se i test sono @Transactional e vuoi ripulire stato del database impegnati, è possibile indicare primavera per eseguire lo script SQL clean-up in una nuova transazione come questo:

@Test 
@Sql("insert-test-data.sql") 
@Sql(
    scripts = "clean-up.sql", 
    executionPhase = AFTER_TEST_METHOD, 
    config = @SqlConfig(transactionMode = ISOLATED) 
) 
public void test() { /* ... */ } 

Spero che questo chiarisca le cose per voi!

Cheers,

Sam (autore del TestContext Spring Framework)


Note:

  • AFTER_TEST_METHOD è importato staticamente da ExecutionPhase
  • ISOLATED è importata staticamente da 012.
+0

Ho una classe astratta annotata con '@ Sql' che esegue alcuni script e una sottoclasse di essa che è anche annotata con' @ Sql'. quando stavo eseguendo il boot di primavera 1.2, tutto funzionava come previsto -> gli script di classe astratti venivano eseguiti prima degli scolari di classe. ma una volta che ho aggiornato a spring boot 1.3, la classe figlio '@ Sql' ha iniziato a scavalcare la classe genitore astratta' @ Sql' e quindi gli script della classe genitore non vengono mai eseguiti. Non so cosa fare ora:/ –

+0

Ho creato una domanda per questo, trovata qui: http://stackoverflow.com/questions/39296329/sub-classing-sql-annotated-class –

Problemi correlati