我有一个非常简单的设置 - 一个调用服务方法的控制器。在此服务中,我将对象保存到数据库,并使用注入的JMSTemplate将JMS消息发送到队列 - 一旦保存。该服务默认启用了事务。
手动测试时 - 在ActiveMQ服务器关闭的情况下 - 抛出异常并回滚事务 - 结果是对象也没有保存到数据库。一切都好。
但是,当我通过集成测试(ActiveMQ仍处于运行状态)运行时,断言,我调用控制器后使用计数查询检查对象是否未保存在DB中,没有说计数是1.我已经确认数据库在测试开始时没有任何这些对象,在测试开始时添加另一个断言以确保计数为0.。
这是预期的行为(可能是由于集成测试环境中事务的性质)还是我可能做错了什么?因为JMS服务器已关闭而仍然抛出异常 - 它是一个RuntimeException。
Grails integration tests and transactions给人的印象是这是预期的 - 在这种情况下,是否有关于如何在集成测试中测试事务行为的最佳实践的建议?
答案 0 :(得分:7)
不确定为什么每个人都评论而不回答,因为评论确实暴露了答案。我会跳进去试图抓住答案点!
是的,在Spock测试中,整个测试,包括时间,天数,数量等都是在同一个交易中用完的。因此,在完成测试之前,您将看不到您希望的回滚。
您可以通过在测试类的顶部添加“static transactional = false”将测试设置为非事务性。当然,结果是您需要在运行测试后清理数据库(如果数据库卫生对您很重要)。这里的一个大问题是Grails IntegrationSpec类中有一个错误,只要你尝试将transactional设置为false,它就会爆炸。这个SO解决了这个问题:
Grails 2.3 IntegrationSpec cannot be transactional false
基本上,将grails.test.spock.IntegrationSpec的所有代码复制到您自己的类中,并使用尊重测试的事务性质的版本替换一些方法。