@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/bean.xml")利用spring对junit的支持,可以很方便的进行测试,同时在测试时,spring提供了依赖注入和事务管理等好处。利用 DBUnit 可以很方便的进行数据库层或者持久层的测试,他在你测试持久层的时候,对数据库的数据有依赖的时候,可以对数据进行准备。你就是为你的创建了,数据库测试环境。因为单元测试必须保证,他们之间的独立性和可重复性,所以每次,DBUnit都可以提供独立的数据库测试环境。说白了,就是DBUnit每次都会按照你的要求,对数据库进行一些操作,从而为你创建数据库测试环境。他只需要几个核心的类,IDataSet 是数据集,IDatabaseConnection 是与数据库的连接,DatabaseOperation 则是最常用的类。他有这么一个方法,
DatabaseOperation#execute(IDatabaseConnection , IDataSet ) ;
DatabaseOperation有这么几种类型:
DatabaseOperation.UPDATE 
DatabaseOperation.INSERT 
DatabaseOperation.DELETE 
DatabaseOperation.DELETE_ALL 
DatabaseOperation.TRUNCATE 
DatabaseOperation.REFRESH 
DatabaseOperation.CLEAN_INSERT 
DatabaseOperation.NONE其他最常用的就是 CLEAN_INSERT,他将数据清空,再插入数据。对Jpa的一些dao进行单元测试的时候,可以利用DBUnit来,进行数据准备,但问题来了。
当你只是测试一些查找方法的时候,没有任何问题。一旦有修改的方法,你就会发现,EntityManager 得到的数据总是与数据库不一致。原因应该是这样的,在进行单元测试的时候,只有两个东西可以修改数据库,一个是DBUnit,另一个就是EntityManager ,大家都知道,EntityManager 维护与数据库的一致状态,他同时也会缓存。问题就在这,EntityManager 缓存了他认为与数据库一致的数据,但其实背后 DBUnit已经在EntityManager 毫不知情的情况下,将数据修改了。这些就出现了,EntityManager与数据库不一致的情况。我刚开始以为是EntityManager使用不当,但多次出现这种诡异的情况,我就有些郁闷,现在总算知道问题了。我想,如果DBUnit用的是EntiyManager 对数据库进行操作,那么这个问题,应该也就不会出现了。不知道还有什么好的方法,请高手指点?

解决方案 »

  1.   

    主动刷新 EntityManager  可否
    或者 你用 DBUnit 更改就用 DBUnit 查询 ,反正你只是测试状态
      

  2.   

    EntityManager refresh是针对某个对象的。你既然对Jpa进行单元测试,然不是DBUnit
      

  3.   

    问题找到了,确实是缓存了,但不是EntityManager 缓存的原因,而是Jpa2的缓存,我每次测试完,我显示的清空缓存就行了。EntityManagerFactory#getCache()#evictAll(); 就OK。
      

  4.   

    楼主用的是JPA2,缓存导致了与数据库的数据的不一致,可以调用缓存接口,显式刷新缓存数据到数据库