Junit + Derby + Spring:テストするたびにインメモリーDBをドロップします
-
12-10-2019 - |
質問
私のユニットテストでは、いくつかのデータソースを自動化しました。
jdbc:derby:memory:mydb;create=true
インメモリDBを作成します。
インメモリダービーDBをドロップするには、次のことを接続する必要があります。
jdbc:derby:memory:mydb;drop=true
私はこれをすべてのテストの後に起こり、新鮮なDBから始めたいと思います。スプリングを使用してこれを行うにはどうすればよいですか?
解決 2
ダービーインメモリデータベースを適切にシャットダウンする方法
解決策へのヒントをくれました。
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
}
}
欠点は、文字列(不変の文字列オブジェクトの周りに不変の文字列オブジェクト)を受け入れる文字列コンストラクターの使用です。スプリング3には@valueアノテーションがあることを読みましたが、ここでは役立つかもしれませんが、春2.5を使用しています。
より良い解決策がある場合はお知らせください。
他のヒント
SpringをHibernateと一緒に使用している場合、これを行うためのデータベースに依存しない方法があります。
すべてのテスト方法の前後にアプリケーションコンテキストが作成 /破壊されることを確認してください。
@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 {
}
Hibernateに、起動時にスキーマを作成し、シャットダウンでスキーマをドロップするように指示します。
hibernate.hbm2ddl.auto = create-drop
今、すべてのテストの前に
- アプリケーションコンテキストが作成され、必要なスプリングビーンズが注入されます(スプリング)
- データベース構造が作成されます(冬眠)
- Import.sqlが存在する場合は実行されます(hibernate)
そして、すべてのテストの後
- アプリケーションコンテキストが破壊されます(春)
- データベーススキーマが削除されます(冬眠)。
トランザクションを使用している場合は、 TransactionalTestExecutionListener
.
春のテスト3の後、注釈を使用して構成を注入できます。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/spring-test.xml")
public class MyTest {
}
次のようなことをするだけです
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;
}
}
豆にプロトタイプの範囲を持たせる(scope="prototype"
)。これにより、すべてのテストの前にデータソースの新しいインスタンスが取得されます。
使用する場合 spring-test.jar 図書館、あなたはこのようなことをすることができます:
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);
}
}
そして、最新のコメントに基づいた更新されたバージョンは、すべてのテストの前にDBをドロップしてテーブルを再現します。
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);
}
}
これは、すべてのテストの開始時に行うことです。
以前のすべてのオブジェクトをドロップします。
create_table.sqlに記載されているすべてのテーブルを作成します
テストするものに基づいて、作成されたテーブルに値を挿入します。
@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"); }
魅力のように機能します!