是否可以测试流程的交易性?

时间:2010-10-26 10:54:32

标签: java database spring jpa transactional

我希望能够验证每个工作单元是在自己的事务中完成的,还是作为单个全局事务的一部分完成的。

我有一个方法(使用spring和hibernate定义),其格式为:

private void updateUser() {
    updateSomething();
    updateSomethingElse();
}

这是从两个地方调用的,即用户登录时的网站和每天运行的批处理作业。对于Web服务器上下文,它将与Web服务器创建的事务一起运行。对于批处理作业,每个用户必须有一个事务,因此如果在此方法期间出现故障,则回滚事务。所以我们有两种方法:

@Transactional(propagation=Propagation.REQUIRES_NEW)
public void updateUserCreateNewTransaction() {
    updateUser();
}

@Transactional(propagation=Propagation.REQUIRED)
public void updateUserWithExistingTransaction() {
    updateUser();
}

updateUserCreateNewTransaction()从批处理作业调用,updateUserWithExistingTransaction()从Web服务器上下文调用。

这很有效。但是,(批量)的这种行为不能改变是非常重要的,所以我希望创建一个测试这种行为的测试。如果可能的话,我想在不更改代码的情况下这样做。

所以对我开放的一些选择是:

  1. 计算在中打开的交易 批处理运行期间的数据库 工作

  2. 在updateSomethingElse()方法中以某种sublte方式更改数据,以便至少有一次用户更新失败,并检查该用户的updateSomething()是否未发生。

  3. 代码审核。

  4. 1是一个非常依赖数据库的方法,我如何保证hibernate不会创建事务呢? 2似乎更好,但设置起来非常复杂。 3并不真实,因为我们需要为每个版本做一个。

    那么,有没有人能够通过系统测试或集成测试来测试这段代码?

2 个答案:

答案 0 :(得分:2)

我会尝试使用内存HSQLDB和EasyMock(或其他一些模拟框架)在单元测试工具中设置测试。

然后您可以让updateSomething()方法真正写入HSQL数据库,但使用模拟框架模拟updateSomethingElse()方法并从该方法中抛出RuntimeException。完成后,您可以对HSQLDB执行查询,以验证updateSomething()内容是否已回滚。

这将需要一些管道来设置HSQLDB和事务管理器,但是当这样做时,你有一个没有外部依赖的测试,只要你愿意,就可以重新运行。

答案 1 :(得分:0)

您可以做的另一件事是为Hibernate的事务配置日志输出:

http://docs.jboss.org/hibernate/core/3.3/reference/en/html/session-configuration.html#configuration-logging

如果你使用跟踪日志级别为org.hibernate.transaction创建一个log4j类别,它应该告诉Hibernate在单元测试期间做事务的所有事情。