2014-11-25 6 views
9

Ich versuche, die folgen Anmerkungen ausführen zu kombinieren:Wie @sql vor einem @Before Methode

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

Wie der Folgecode:

@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"); 
} 

der Code in der Methode @Before nach dann dem Skript "DML-parametro.sql" in der @sql Anmerkung läuft.

Ist es richtig, dies zu tun?

Für Lösung dies, ich benutze @ After nach Ort als @Before, aber ich möchte Tabellen vor der Testausführung, nicht nach.

Ich möchte nicht @SqlConfig verwenden. Ich benutze keinen transacionalen Bereich auf Testniveau, also muss ich meine Tabellen in jeder Testmethode reinigen. Wenn jede Testmethode Tabellen bereinigen muss, möchte ich dies in @Before Methode tun. Ich möchte das nicht bei jeder Testmethode mit @SqlConfig machen. Ich denke, dass das Verhalten von @Sql vor dem Ausführen von @Before falsch ist.

Antwort

31

Standardmäßig werden alle SQL-Skripte, die über @Sql ausgeführt werden, vor beliebigen @Before Methoden ausgeführt. Das Verhalten ist also korrekt, aber Sie können die Ausführungsphase über das executionPhase Attribut in @Sql ändern (siehe Beispiel unten).

Wenn Sie mehrere Skripte ausführen möchten, ist dies auch über @Sql möglich.

Also, wenn Sie einen Clean-up-Skript clean-parametro.sql benannt, die aus der PARAMETRO Tabelle löscht, können Sie Ihre Testverfahren wie folgt aus (statt JdbcTestUtils.deleteFromTables() in Ihrer @Before Methode aufgerufen) mit Anmerkungen versehen.

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

Natürlich, wenn dml-parametro.sql Einsätze Werte in die PARAMETRO Tabelle, dann Sinn es macht wahrscheinlich nicht sofort auf diese Werte in dem Clean-up-Skript zu löschen.

Bitte beachten Sie, dass @Sql und @SqlConfig mehrere Konfigurationsebenen für die Skriptausführung bieten.

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

Oder @SqlGroup als Container auf Java 6 verwenden oder:

Zum Beispiel, wenn Sie Tabellen, bevor Sie Ihren Test erstellen möchten und reinigen Sie nach dem Test, konnte man so etwas wie dies auf Java 8 tun 7 Java:

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

Wenn Ihre Tests @Transactional sind und Sie möchten, dass engagierte Datenbank Zustand bereinigen, Sie Frühling anweisen können Ihre Bereinigungs SQL-Skript in einer neuen Transaktion wie folgt auszuführen:

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

Ich hoffe, dies klärt die Dinge für Sie!

Cheers,

Sam (Autor des Frühlings Testcontext-Framework)


Hinweise:

  • AFTER_TEST_METHOD statisch importiert von ExecutionPhase
  • ISOLATED statisch importiert aus TransactionMode
+0

Ich habe eine abstrakte Klasse mit '@ Sql' annotiert, die einige Skripte ausführt, und eine Unterklasse, die ebenfalls mit '@ Sql' versehen ist. Als ich Springboot 1.2 ausführte, funktionierte alles wie erwartet -> abstrakte Klassenskripte wurden vor Kindklassen-Skripten ausgeführt. Aber sobald ich auf Spring Boot 1.3 aktualisiert habe, begann die Kind-Klasse '@ Sql' die abstrakte '@ Sql'-Klasse der übergeordneten Klasse zu überschreiben und somit werden Parent-Class-Skripte niemals ausgeführt. Ich weiß nicht, was ich jetzt tun soll:/ –

+0

Ich habe eine Frage dafür erstellt, hier gefunden: http://stackoverflow.com/questions/39296329/sub-classing-sql-annotated-class –

Verwandte Themen