我正在爲我正在編寫的Spring/Hibernate應用程序編寫一些集成測試,並且我想盡可能接近真實條件來測試,包括使用Hibernate的二級緩存和提交事務。簡單的方法來截斷所有表,清除第一級和第二級休眠緩存?
我想知道是否有一種有效的方法讓Hibernate從數據庫和緩存中刪除所有內容。我能想到的最好方法是使用HQL「從XImpl中刪除」行來查看每種類型的對象,但我有幾十個域對象,感覺應該有更好的方法。
我正在爲我正在編寫的Spring/Hibernate應用程序編寫一些集成測試,並且我想盡可能接近真實條件來測試,包括使用Hibernate的二級緩存和提交事務。簡單的方法來截斷所有表,清除第一級和第二級休眠緩存?
我想知道是否有一種有效的方法讓Hibernate從數據庫和緩存中刪除所有內容。我能想到的最好方法是使用HQL「從XImpl中刪除」行來查看每種類型的對象,但我有幾十個域對象,感覺應該有更好的方法。
對於數據庫,使用SchemaExport
工具來重新架構:
Configuration cfg = ....;
new SchemaExport(cfg).create(false, true);
對於二級緩存,從SessionFactory
獲得訪問底層的緩存區域和驅逐一切:
SessionFactory sf = ...;
Cache cache = sf.getCache();
cache.evictEntityRegions();
cache.evictCollectionRegions();
cache.evictQueryRegions();
對於一級緩存,只需獲取新的Session
或致電session.clear()
。
考慮到上面的Pascal方法,我找到了在Spring中創建SchemaUpdate對象的正確方法,並意識到我不需要。相反,我可以獲取Spring的SessionFactory對象,並要求它放棄/創建模式。結合Pascal的解決方案的其餘部分,我們得到這個:
LocalSessionFactoryBean localSessionFactoryBean = (LocalSessionFactoryBean)appContext.getBean("&sessionFactory");
localSessionFactoryBean.dropDatabaseSchema();
localSessionFactoryBean.createDatabaseSchema();
Cache cache = sf.getCache();
cache.evictEntityRegions();
cache.evictCollectionRegions();
cache.evictQueryRegions();
這是非常有效的。唯一的缺點是(至少對我來說)比每個表名稱中的「從obj1中刪除」,「從obj2中刪除」要慢得多。不過,我喜歡不必重複自己。
看看Unitils。它對database testing(使用DbUnit)有很大的支持,我們已經使用了很長一段時間。它非常靈活,所以如果您發現需要將數據預加載到數據庫中以進行特定的單元測試,那麼您可以使用它。
隨着Unitils,您將創建表示空數據庫中的數據集文件(empty-db.xml
):
<?xml version='1.0' encoding='UTF-8'?>
<dataset>
<obj1/>
<obj2/>
</dataset>
在需要配置數據集
@DataSet("empty-db.xml")
類或測試我們對所有持久性測試都有一個共同的基類,所以我們能夠將註釋放在一個地方。
不利的一面是,每次向Hibernate添加實體時,您都必須爲此文件添加行。而且您必須獲得與外鍵約束一致的訂單。我們最終添加了一個單元測試來檢查這個文件是否與Hibernate配置保持一致。
另一方面,特別是對於大型模式,它的速度比重建模式要快。
SchemaExport!非常棒的主意 - 星期一我會嘗試一下。 – 2010-06-27 20:49:07