dbunitによるデータベース操作のテスト

4619 ワード

j 2 eeプログラムの多くはデータベース操作に関わるが、この場合mockテストを行うことは意味がないので、直接データベース上で操作するほうがよい.
データベースのテストには2つの要件があります.
1テスト前のデータベースは確定的な状態である.
2テストはデータベースの状態を変更しない.
比較的良い方法は専用のテストデータベースを構築し、テストデータの干渉を避けることだと思います.そうでなければ、テストが終了するたびに、対応する現場復旧が行われる.
データベースallcrapを開発し、テストデータベースallcrapを構築するとします.test.データベース・テーブル構造の一貫性を保証するために、手動で同期したりmysqldumpで実行したりすることができます.
.\mysqldump.exe -u root -proot allcrap -d > ddl.sql
このコマンドはallcrapデータベースDDL文を導出、-dオプションはデータを導出しないことを示し、DDL文をテストライブラリにインポートすればよい.
.\mysql -u root -proot allcrap_test データベース構造の同期後、データベース内のデータを特定の状態にするには、dbunitのDataSetで実現することができる.
DataSetは、データベース内のデータに対応する、データベースを初期化することができる.
allcrapデータベースにテーブルproductがありますddlは

CREATE TABLE `product` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  `price` decimal(10,2) NOT NULL,
  `vender_id` int(11) DEFAULT NULL,
  `optlock` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `product_fk_vendor_id` (`vender_id`),
  CONSTRAINT `product_fk_vendor_id` FOREIGN KEY (`vender_id`) REFERENCES `vendor` (`id`)
) ENGINE=InnoDB

対応するdatasetは

<dataset>
    <product name=" " price="3699" id="1" optlock="0"/>
    <product name="  3200+" price="400" id="2" optlock="0"/>
    <product name=" " price="600" id="3" optlock="0"/> 
</dataset>

これによりdbunitは、各テストの前にデータベースのproductテーブルをこの3つのデータに初期化することができる.
その後の各テストは確定的な状態に確立する、人工的な介入を必要とせずにプログラムで自動化テストを行うことができる.
これにより、毎日、タイミングタスクでテストを行うことができる.
dbunitのtestcaseは次のとおりです.

public class ProductDaoTest extends DBTestCase {

 public ProductDaoTest() {
  System.setProperty(
    PropertiesBasedJdbcDatabaseTester.DBUNIT_DRIVER_CLASS,
    "com.mysql.jdbc.Driver");
  System.setProperty(
    PropertiesBasedJdbcDatabaseTester.DBUNIT_CONNECTION_URL,
    "jdbc:mysql://localhost/allcrap_test");
  System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_USERNAME,
    "root");
  System.setProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_PASSWORD,
    "root");
 }

 @Override
 protected IDataSet getDataSet() throws Exception {
  return new FlatXmlDataSetBuilder().build(new FileInputStream(
    ".\\bin.\\product_dataset.xml"));
 }

 private ProductDao productDao;
 private SessionFactory sessionFactory;
 private Session session;

 @Override
 protected void setUp() throws Exception {
  super.setUp();
  sessionFactory = new Configuration()
    .configure("hibernate_test.cfg.xml").buildSessionFactory();
  this.session = sessionFactory.openSession();
  productDao = new ProductDao();
  productDao.setSession(session);
 }

 @Override
 protected void tearDown() throws Exception {
  if (this.session != null) {
   this.session.close();
  }
  if (this.sessionFactory != null) {
   this.sessionFactory.close();
  }
  super.tearDown();

 }

 private void beginTx() {
  this.session.beginTransaction();
 }

 private void commit() {
  this.session.getTransaction().commit();
 }

 @Test
 public void testBasicCRUD() {
  this.beginTx();
  Product p = this.productDao.load(2);
  assertEquals(Integer.valueOf(2), p.getId());

  Product newProduct = new Product();
  newProduct.setName("testProduct");
  newProduct.setPrice(BigDecimal.valueOf(34.2));
  this.productDao.save(newProduct);
  this.commit();
  
  
  try {
   assertEquals("testProduct", this.getConnection()
     .createDataSet().getTable("product").getValue(3, "name"));
  } catch (Exception e) {
   e.printStackTrace();
  }

 }

 @Test
 public void testProductListByPrice() {
  this.beginTx();
  List<Product> productList = this.productDao.findProductListByPrice(
    new BigDecimal(400), new BigDecimal(600));
  assertEquals(2, productList.size());
  assertEquals(Integer.valueOf(2), productList.get(0).getId());
  assertEquals(Integer.valueOf(3), productList.get(1).getId());
  this.commit();
 }
}