[英]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將執行以下操作:
因此,當執行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.