簡體   English   中英

DBUnit不會在每個方法之后清理並插入數據庫,因此測試不是獨立的

[英]DBUnit not cleaning and insert the database after every method, so test are not independent

我有一個DAO類的測試,我使用DBUnit來創建和填充數據庫(使用內存中的德比)。 我在測試dao update方法時遇到問題,因為它修改數據然后另一個測試失敗。 因為我們所有人都知道測試應該獨立於任何其他測試,並且我知道DBUnit在每次測試后都有一些清理和重新生成數據庫的工具。 但它不起作用!

代碼就是這個(TestNG):

@BeforeMethod
public void prepareData() throws Exception {
  cleanAndPopulate("users");
}

public void cleanAndPopulate (String nameXML) throws Exception {
  IDatabaseConnection conn; 
  conn = new DatabaseConnection (sessionForTesting.connection());        
  InputStream is = DBconnection.class.getClassLoader()
    .getResourceAsStream(nameXML + ".xml");      
  dataset = new FlatXmlDataSet(is);
  System.out.println("*** Preparando base de datos de test"); 
  DatabaseOperation.CLEAN_INSERT.execute(conn, dataset); 
}

這是測試(禁用以避免附帶影響):

@Test(enabled=false) // Deja la BBDD en estado erroneo!!!
public void busco_y_actualizo() throws Exception { 
    PacoUser resultado = userdao.getById(1L);
    resultado.setName("OTRO");
    userdao.update(resultado);
    PacoUser resultado2 = userdao.getById(1L);
    AssertJUnit.assertNotNull(resultado2); 
    AssertJUnit.assertEquals("OTRO", resultado2.getName());    
}

這是因為CLEAN_INSERT在測試之前“清潔”,而不是在測試之后。

例如,如果有兩個測試,test1和test2。 test1和test2分別從test1.xml和test2.xml填充表。

test1.xml就像

<dataset>
  <table1 ... />
  <table2 ... />
</dataset>

test2.xml就好

<dataset>
  <table1 ... />
</dataset>

當測試的順序是test1然后是test2時,CLEAN_INSERT將執行以下操作:

  1. 從table2中刪除所有內容
  2. 從table1中刪除所有內容
  3. 將test1.xml中的數據插入table1
  4. 將test1.xml中的數據插入table2
  5. 執行test1
  6. 從table1中刪除所有內容
  7. 將test2.xml中的數據插入table1
  8. 執行test2

因此,當執行test2時,table1包含來自test2.xml的數據,這正是我們所期望的。 但是table2仍然包含test1的數據,這可能會導致一些問題。

解決方法是在所有xml文件中為每個表創建一個空行。 它將確保在插入之前清除所有表格。

對於上面的例子,

test1.xml會是這樣的

<dataset>
  <table1 ... />
  <table2 ... />
  <table1 />
  <table2 />
</dataset>

test2.xml就好

<dataset>
  <table1 ... />
  <table1 />
  <table2 />
</dataset> 
@After
public void after() throws SQLException {
    Session session = hibernateSessionFactory.openSession();
    try {
        Work work = new Work() {

            @Override
            public void execute(Connection connection) throws SQLException {
                IDatabaseConnection dbConn = null;
                try {
                    dbConn = getConnection(connection);
                } catch (DatabaseUnitException e) {
                    logger.error("Exception in before", e);
                    Assert.fail(e.getMessage());
                }

                try {
                    List<String> resultList = (List<String>) hibernateTemplate
                            .execute(new HibernateCallback() {
                                String sql = "SELECT st.TABLE_NAME FROM INFORMATION_SCHEMA.SYSTEM_TABLES st where st. TABLE_TYPE='TABLE'";

                                public List<String> doInHibernate(
                                        Session session)
                                        throws HibernateException,
                                        SQLException {
                                    Query query = session
                                            .createSQLQuery(sql);
                                    List<String> list = query.list();
                                    return list;
                                }
                            });

                    QueryDataSet partialDataSet = new QueryDataSet(dbConn);
                    for (String tableName : resultList) {
                        partialDataSet.addTable(tableName);
                    }

                    DatabaseOperation.DELETE_ALL.execute(dbConn,
                            partialDataSet);

                } catch (Exception e) {
                    logger.error("Exception in after", e);
                    Assert.fail(e.getMessage());
                } finally {
                    dbConn.close();
                }

            }

        };
        session.doWork(work);

    } catch (Exception e) {
        logger.error("Exception in after", e);
        Assert.fail(e.getMessage());
    } finally {
        session.close();
    }
}

protected DatabaseConnection getConnection(Connection connection)
        throws DatabaseUnitException, SQLException {
    return new DatabaseConnection(connection, SCHEMA);
}

確保在每個測試用例之前重置數據庫以確保測試獨立性。 @BeforeMethod僅在所有測試用例運行之前調用一次,因此將cleanAndPopulate放在此處是不夠的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM