H 2+Dbunit+JUnitによるデータベース関連テスト
6029 ワード
H 2+Dbunit+JUnitによるデータベース関連テスト
多くの場合、私たちはテストを書くときに、データベースにアクセスする必要がある機能をテストする必要があります.このようなテストを処理するとき、テストがテストシーンをシミュレートし、繰り返し実行できることを保証するために、簡単なデータ準備ツールが必要です.分離されたクリーンなデータベース環境.
以上の目標を達成するために、同僚が愛用しているさまざまなModelのBuilder+データベーストランザクションロールバック(ライブラリ間問題)や、実行するたびにデータベースを消去してからDbunit(独自のライブラリがなければ他の同僚の仕事に影響を与えることが多い)など、多くの方法で達成できます.
最後に自分で選んだ方法は、builder(挿入するデータの準備)とDbunitを組み合わせ、H 2データベースを使用してメモリモードとMySQL互換モードをオンにしてデータベースに関するテストを処理することです.(はい、Spring-Sideのテスト方法を学びました(*^^*)このようにテストのたびにかなりきれいな環境ができ、テストのために単独でライブラリを構築する必要はありません.
Dbunit、H 2の詳細については、関連ドキュメントを参照してください.ここでは詳しく説明しません.H 2Dbunitと組み合わせてテストする方法について説明します.
まず、H 2データベースを準備する必要があります.H 2が「埋め込み型」データベースである以上、従来のデータベースの「インストール」プロセスは必要ありません.mavenを使用する場合は、依存パッケージを追加するだけです.
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.3.160</version>
<scope>test</scope>
</dependency>
コードにh 2を直接接続して使用することができます.
次に、次の操作のためにデータ・ソースを取得します.
ここでは、プロジェクトがspringを使用しているか、Spring Embedded database support(http://static.springsource.org/spring/docs/3.0.0.M4/spring-framework-reference/html/ch12s08.html)
<jdbc:embedded-database id="dataSource">
<jdbc:script location="classpath:schema.sql"/>
<jdbc:script location="classpath:test-data.sql"/>
</jdbc:embedded-database>
そしてdataSourceはあなたに所有されています...しかし、この使用中に発見された問題は、embedded-databaseラベルを使用することで接続URLを自分で定義することができずMySQLモードを開くことです.プロジェクトがmybatisを使用するとHibernateのようなORMではsql構文の不一致の問題を処理することができず、最後に使用を選択しませんでした.
springを使用して構成データソースを管理する必要がある場合は、DataSourceFactoryBeanを実装することを考慮します.URL、ユーザー名、パスワード、およびテーブル作成スクリプトパスを構成し、beanの初期化時に構成されたテーブル作成文でテーブルを作成できます.
次にspringを使用していない場合、古い方法を使用してデータベースに直接接続します.
public final class H2DatabaseUtil {
private static final Logger logger = LoggerFactory.getLogger(H2DatabaseUtil.class);
private H2DatabaseUtil() {
}
public static DataSource getDataSource() {
if (logger.isDebugEnabled()) {
logger.debug("get H2 data source.");
}
SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
dataSource.setDriverClass(org.h2.Driver.class);
dataSource.setUsername("sa");
dataSource.setPassword("");
dataSource.setUrl("jdbc:h2:mem:testdb;MODE=MYSQL;DB_CLOSE_DELAY=-1");
return dataSource;
}
public static void initSchema(DataSource ds) {
if (logger.isDebugEnabled()) {
logger.debug("start init schema.");
}
try {
QueryRunner queryRunner = new QueryRunner(ds);
queryRunner.update("drop all objects");
if (logger.isDebugEnabled()) {
logger.debug("delete all object k.o.");
}
try {
queryRunner.update("runscript from '"
+ new DefaultResourceLoader()
.getResource("schema.sql").getURL().toString() + "'");
if (logger.isDebugEnabled()) {
logger.debug("rebuild the schema finish! f~resh meat...");
}
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
} catch (SQLException e) {
logger.error(e.getMessage(),e);
}
}
}
DbUtils , DataSource , 。
Test dataSource
public abstract class AbstractDBAwareTestCase {
protected QueryRunner queryRunner ;
protected DataSource dataSource;
protected void setUp() throws Exception {
dataSource = getDataSource();
initSchema(dataSource);
queryRunner = new QueryRunner(dataSource);
}
}
。
, Dbunit 。
Dbunit ? copy spring-side Fixtures
(http://springside.googlecode.com/svn/springside4/trunk/modules/core/src/main/java/org/springside/modules/test/data/Fixtures.java)
spring resource ( classpath ), 。
Test :
public class AgentRepositoryTest extends AbstractDBAwareTestCase {
private IAgentRepository agentRepository;
@Before
public void setUp() throws Exception {
super.setUp();
reloadAllTable(dataSource, "/data/agent-data.xml");
agentRepository = Lookup.getDefault().lookup(IAgentRepository.class);
}
@Test
public void should_find_agent_by_id() throws Exception {
Agent agent = agentRepository.findById(dataSource, 1);
assertNotNull(agent);
assertThat(agent.getSimpleName(), is("demoa"));
}
}
setUpまたはテスト開始前にreloadloadデータを使用すると、必要なテスト「シーン」が得られます.
分かち合うことができるのはこれだけで、他に良い方法があれば交流を歓迎します!thx
ps:H 2のMySQLモードを使用していますが、テーブル文のcommentinnodbtinyintなど、互換性のない文もあります.