JUnit + Derby + Spring: Drop In-Memory-db nach jedem Test
-
12-10-2019 - |
Frage
In meinen Unit-Tests autowired ich einige Datasources, die URLs wie
verwendenjdbc:derby:memory:mydb;create=true
Ein In-Memory-DBs erstellen.
Um ein In-Memory-Derby fällt db Sie verbinden müssen:
jdbc:derby:memory:mydb;drop=true
Ich würde dies gerne nach jedem Test passieren und mit einem frischen db starten. Wie kann ich das mit Spring?
tunLösung 2
Wie zum Herunterfahren Derby in-Memory-Datenbank ordnungsgemäß
gab mir einen Hinweis auf eine Lösung:
mydb.drop.url = jdbc:derby:memory:mydb;drop=true
...
<bean id="mydbDropUrl" class="java.lang.String">
<constructor-arg value="${mydb.drop.url}" />
</bean>
...
@Resource
private String mydbDropUrl;
@After
public void tearDown() {
try {
DriverManager.getConnection(mydbDropUrl);
} catch (SQLException e) {
// ignore
}
}
Ein Nachteil ist die Verwendung des Schnur-Konstruktors, die einen String (um ein unveränderliches String-Objekt ein unveränderliches Objekt String) übernimmt. Ich habe gelesen, dass es eine @Value Anmerkung im Frühling ist 3, die hier helfen könnte, aber ich bin mit Spring 2.5.
Bitte lassen Sie mich wissen, wenn Sie eine schönere Lösung haben.
Andere Tipps
Es ist eine Datenbank-unabhängige Art und Weise, dies zu tun, wenn Sie Frühling verwenden zusammen mit Hibernate.
Stellen Sie sicher, dass der Anwendungskontext vor erstellt / zerstört wird / nach jeder Testmethode:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath*:application-context-test.xml"})
@TestExecutionListeners({DirtiesContextTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class})
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
public abstract class AbstractTest {
}
Instruct Hibernate automatisch das Schema beim Start erstellen und das Schema beim Herunterfahren löschen:
hibernate.hbm2ddl.auto = create-drop
Jetzt vor jedem Test
- der Anwendungskontext wird erstellt und die erforderliche Feder Bohnen injizieren (Feder)
- die Datenbankstrukturen geschaffen werden (Hibernate)
- die import.sql wird ausgeführt, wenn vorhanden (Hibernate)
und nach jedem Test
- der Anwendungskontext zerstört (Feder)
- das Datenbankschema fallen gelassen wird (Hibernate).
Wenn Sie Transaktionen verwenden, können Sie die TransactionalTestExecutionListener
hinzufügen möchten.
Nach dem Feder Test 3 können Sie Anmerkungen verwenden, um Konfigurationen zu injizieren:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/spring-test.xml")
public class MyTest {
}
Genau das tun, so etwas wie:
public class DatabaseTest implements ApplicationContextAware {
private ApplicationContext context;
private DataSource source;
public void setApplicationContext(ApplicationContext applicationContext) {
this.context = applicationContext;
}
@Before
public void before() {
source = (DataSource) dataSource.getBean("dataSource", DataSource.class);
}
@After
public void after() {
source = null;
}
}
Machen Sie Ihre Bohne einen Umfang von Prototypen (scope="prototype"
) haben. Dies wird eine neue Instanz der Datenquelle vor jedem Test erhalten.
Wenn Sie die feder test.jar Bibliothek, können Sie etwas tun:
public class MyDataSourceSpringTest extends
AbstractTransactionalDataSourceSpringContextTests {
@Override
protected String[] getConfigLocations() {
return new String[]{"classpath:test-context.xml"};
}
@Override
protected void onSetUpInTransaction() throws Exception {
super.deleteFromTables(new String[]{"myTable"});
super.executeSqlScript("file:db/load_data.sql", true);
}
}
Und eine aktualisierte Version auf den neuesten Kommentar basiert, die db und wieder aufs Neue schafft Tabellen vor jedem Test fällt:
public class MyDataSourceSpringTest extends
AbstractTransactionalDataSourceSpringContextTests {
@Override
protected String[] getConfigLocations() {
return new String[]{"classpath:test-context.xml"};
}
@Override
protected void onSetUpInTransaction() throws Exception {
super.executeSqlScript("file:db/recreate_tables.sql", true);
}
}
Dies ist, was wir zu Beginn jeden Test zu tun.
-
Drop alle bisherigen Objekte.
-
Erstellen Sie alle Tabellen in der genannten create_table.sql
-
Legen Sie Werte auf die erstellten Tabellen auf, was Sie testen möchten.
@Before public void initialInMemoryDatabase() throws IOException, FileNotFoundException { inMemoryDerbyDatabase.dropAllObjects(); inMemoryDerbyDatabase.executeSqlFile("/create_table_policy_version_manager.sql"); inMemoryDerbyDatabase.executeSqlFile("/insert_table_policy_version_manager.sql"); }
Arbeiten wie ein Charme!