5

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

我有一个方法(使用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(),从 Web 服务器上下文调用 updateUserWithExistingTransaction()。

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

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

  1. 计算批处理作业运行期间在数据库中打开的事务。

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

  3. 代码审查。

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

那么,有没有人有一种方法可以让我测试这段代码,最好是通过系统测试或集成测试?

4

2 回答 2

2

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

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

设置 HSQLDB 和事务管理器将需要一些管道,但完成后,您将获得一个没有外部依赖项的测试,可以随时重新运行。

于 2010-10-26T12:09:46.320 回答
0

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

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

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

于 2011-09-20T14:28:28.067 回答