我正在尝试构建一些关于经过审计的实体的测试。我的问题是envers仅在事务提交时进行审计。
我需要创建/编辑一些测试对象,提交事务,然后检查修订记录。
使用envers进行集成测试的最佳方法是什么?
更新:这是一个非常糟糕、不确定的测试类,展示了我想要实现的内容。我希望在不依赖测试方法顺序的情况下完成这个过程。
首先,在单个事务中创建一个帐户和一个帐户交易。这两个经过审计的条目都是修订版本1。
第二步,在新的事务中更新帐户交易。经过审计的条目在修订版本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);
}
DbResetRule
- 我的想法是避免在JUnit测试中使用@Transactional
,而是让您的代码提交和回滚事务。显然,这使得测试不可重复且脆弱。但是,我建议不要回滚更改,而是在每个测试之前/之后倾倒数据库并恢复它。代码是用Scala编写的,但这只是一个通用想法。如果这符合您的要求,请告诉我,我会在另一个答案中详细说明。 - Tomasz Nurkiewicz@Transactional
注释方法时,您不必手动执行任何操作。看起来您已经在这样做了。但是,当您从测试中删除@Transactional
时,您不能在测试中简单地使用EntityManager
。 要么将其访问包装在事务型bean中,要么使用TransactionTemplate
。 - Tomasz Nurkiewicz