是否可以测试流程的事务性?
我希望能够验证每个工作单元是否在其自己的事务中完成,或者作为单个全局事务的一部分完成。
我有一个方法(使用 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()。
这有效。但是,(批次的)这种行为不被改变是非常重要的,所以我希望创建一个测试来测试这种行为。如果可能的话,我想在不更改代码的情况下完成此操作。
因此,我可以选择的一些选项是:
计算在 批处理运行期间的数据库 job.
- ,以便在 updateSomethingElse() 方法中至少有一个用户更新失败,并检查该用户的 updateSomething() 尚未发生。
代码审查。
1 是一个非常依赖数据库的方法,我如何保证 hibernate 无论如何都不会创建事务? 2 似乎更好,但设置起来非常复杂。 3 不太实用,因为我们需要为每个版本都执行一个。
那么,有没有人有一种方法可以让我测试这段代码,最好是通过系统测试或集成测试?
I would like to be able to verify if each unit of work is done in its own transaction, or as part of a single global transaction.
I have a method (defined using spring and hibernate), which is of the form:
private void updateUser() {
updateSomething();
updateSomethingElse();
}
This is called from two places, the website when a user logs in and a batch job which runs daily. For the web server context, it will run with a transaction created by the web server. For the batch job, it must have one transaction for each user, so that if something fails during this method, the transaction is rolled back. So we have two methods:
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void updateUserCreateNewTransaction() {
updateUser();
}
@Transactional(propagation=Propagation.REQUIRED)
public void updateUserWithExistingTransaction() {
updateUser();
}
updateUserCreateNewTransaction() is called from the batch job, and updateUserWithExistingTransaction() from the web server context.
This works. However, it is very important that this behaviour (of the batch) not be changed, so I wish to create a test that tests this behaviour. If possible, I would like to do this without changing the code.
So some of the options open to me are:
Count the transactions opened in the
database during the run of the batch
job.Change the data in some sublte way so that at least one user update fails, in the updateSomethingElse() method, and check that the updateSomething() for that user has not taken place.
Code review.
1 is a very database dependent method, and how do I guarantee that hibernate won't create a transaction anyway?. 2 seems better, but is very complex to set up. 3 is not really practical because we will need to do one for every release.
So, does anyone have a method which would enable me to test this code, preferably through a system test or integration test?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我会尝试使用内存中的 HSQLDB 和 EasyMock (或其他一些模拟框架)在单元测试工具中设置测试。
然后,您可以让
updateSomething()
方法真正写入 HSQL 数据库,但使用模拟框架来模拟updateSomethingElse()
方法并抛出RuntimeException 来自该方法。完成后,您可以对 HSQLDB 执行查询以验证 updateSomething() 内容是否已回滚。
它需要一些管道来设置 HSQLDB 和事务管理器,但是完成后,您就可以进行没有外部依赖项的测试,并且可以随时重新运行。
I would try to setup a test in a unit test harness using an in memory HSQLDB and EasyMock (or some other mocking framework).
You could then have the
updateSomething()
method really write to the HSQL database but use the mock framework to mock theupdateSomethingElse()
method and throw aRuntimeException
from that method. When that is done you could perform a query against the HSQLDB to verify that theupdateSomething()
stuff was rolled back.It will require some plumbing to setup the HSQLDB and transaction manager but when that is done you have a test without external dependencies that can be re-run whenever you like.
您可以做的另一件事是配置 Hibernate 事务的日志输出:
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/session-configuration.html#configuration-logging
如果您为 org. hibernate.transaction 具有跟踪日志级别,它应该告诉 Hibernate 在单元测试期间以事务方式执行的所有操作。
Another thing you can do is configure logging output for Hibernate's transactions:
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/session-configuration.html#configuration-logging
If you make a log4j category for org.hibernate.transaction with trace log leve, it should tell everything that Hibernate does transaction-wise during a unit test.