使用Hibernate Envers进行集成测试

Kar*_*lsh 8 integration-testing hibernate jpa-2.0 hibernate-envers

我正在尝试围绕一些被审计的实体构建一些测试.我的问题是envers只审计事务提交.

我需要创建/编辑一些测试对象,提交事务然后检查修订.

与envers进行集成测试的最佳方法是什么?

更新:这是我想要实现的非常糟糕的,非确定性的测试类.我更愿意这样做,而不依赖于测试方法的顺序

首先在单个事务中创建帐户和account_transaction.两个审计条目均适用于修订版1.

第二次更新了新事务中的account_transaction.经审计的条目为修订版2.

第三,在修订版1中加载审计帐户并对其执行某些操作.

@Transactional
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/testApplicationContext.xml"})
public class TestAuditing {

    @Autowired
    private AccountDao accountDao;

    @PersistenceContext
    private EntityManager entityManager;

    @Test
    @Rollback(false)
    public void first() {
        Account account = account("Test Account", "xxxxxxxx", "xxxxxx");

        AccountTransaction transaction = transaction(new Date(), Deposit, 100, "Deposit");
        account.setTransactions(newArrayList(transaction));

        accountDao.create(account);
    }

    @Test
    @Rollback(false)
    public void second() {
        Account account = accountDao.getById(1L);
        AccountTransaction transaction = account.getTransactions().get(0);
        transaction.setDescription("Updated Transaction");
        accountDao.update(account);
    }

    @Test
    public void third() {
        AuditReader reader = AuditReaderFactory.get(entityManager);

        List<Number> accountRevisions = reader.getRevisions(Account.class, 1L);
        //One revision [1]

        List<Number> transactionRevisions = reader.getRevisions(AccountTransaction.class, 1L);
        //Two revisions [1, 2]

        Account currentAccount = accountDao.getById(1L);
        Account revisionAccount = (Account) reader.createQuery().forEntitiesAtRevision(Account.class, 1).getSingleResult();

        System.out.println(revisionAccount);
    }
Run Code Online (Sandbox Code Playgroud)

Kar*_*lsh 5

根据 Tomasz 的建议,我使用 TransactionTemplate 来实现每个 dao 操作后的提交。没有类级别的 @Transactional 注释。

在方法完成之前插入 envers 审计条目,这正是我所需要的。

@ContextConfiguration("testApplicationContext.xml")
public class TestAuditing extends AbstractJUnit4SpringContextTests {

    @Autowired
    private PlatformTransactionManager platformTransactionManager;

    @Autowired
    private PersonDao personDao;

    private TransactionTemplate template;

    @Before
    public void transactionTemplate() {
         template = new TransactionTemplate(platformTransactionManager);
    }

    @Test
    public void test() {
        Person person = createInTransaction(person("Karl", "Walsh", address("Middle of nowhere")), personDao);
        System.out.println(person);
    }

    private <T> T createInTransaction(final T object, final Dao<?, T> dao) {
        return template.execute(new TransactionCallback<T>() {
            public T doInTransaction(TransactionStatus transactionStatus) {
                dao.create(object);
                return object;
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

我是Spring事务测试支持的用户,该事务在完成后会回滚测试,并且由于envers的设计,因此不会创建修订。我创建了一个hack,该hack似乎允许人们在事务提交之前“告诉” envers手动完成其工作,但允许spring继续回滚。

这些摘要应该有所帮助。1.创建自己的审核侦听器,以覆盖现有的envers审核侦听器。这允许访问对单元测试可见的静态成员。也许有更好的方法,但是它可以工作。

public class AuditEventListenerForUnitTesting extends AuditEventListener {

   public static AuditConfiguration auditConfig;

   @Override
   public void initialize(Configuration cfg) {
      super.initialize(cfg);
      auditConfig = super.getVerCfg();
   }
}
Run Code Online (Sandbox Code Playgroud)

修改您的persistence.xml以包括此新的侦听器类,而不是envers提供的类

(如有必要,请其他听众重复)

现在在“单元”测试中:

{
   saveNewList(owner); //code that does usual entity creation
   em.flush();  
   EventSource hibSession = (EventSource) em.getDelegate();
   AuditEventListenerForUnitTesting.auditConfig.getSyncManager().get(hibSession).doBeforeTransactionCompletion(hibSession);     
   //look for envers revisions now, and they should be there
}
Run Code Online (Sandbox Code Playgroud)

我之所以需要它,是因为我有一些针对休眠实体的JDBC查询,这些休眠实体已加入到版本控制表中。