Grails 2.5.3使用spock测试集成测试的服务回滚

时间:2016-02-25 03:53:09

标签: grails

我有一个相当复杂的服务,可以创建和保存很多域实例,并且由于逻辑原因,我需要在不同的时间创建不同的实例,并在中间检查某些条件,这不仅是每个实例有效,但是例如我需要检查文件系统中是否存在某些文件等。

我正在测试不正确的情况,其中服务抛出异常,我需要测试没有抛出异常的实例。

一个特定的测试用例失败,即使抛出了预期的异常,域实例也保存到了数据库中。然后我读到了,因为集成测试本身是事务性的,回滚确实发生在测试结束时,而不是在使用服务之后,所以我可以检查"然后" spock测试用例的一部分。

因此,如果在我测试之后发生回滚,我就无法测试它:(

然后我读到,使集成测试不是事务可能会有所帮助,所以我补充说:

static transactional = false

在此之后,我的所有其他测试开始失败!

我的问题是:在抛出异常时应该回滚的测试服务的正确方法是什么?我只需要验证在发生异常后,数据库没有任何变更(因为这是医疗保健应用程序,数据一致性是关键)

供参考:

这是我需要测试的服务:https://github.com/ppazos/cabolabs-ehrserver/blob/master/grails-app/services/com/cabolabs/ehrserver/parsers/XmlService.groovy

这是我目前的测试:https://github.com/ppazos/cabolabs-ehrserver/blob/master/test/integration/com/cabolabs/ehrserver/parsers/XmlServiceIntegrationSpec.groovy

谢谢!

1 个答案:

答案 0 :(得分:0)

如果您可以修改代码以依赖框架,那么您就不需要测试框架。

Grails使用Spring,Spring事务管理器自动回滚RuntimeExceptions但不回滚已检查的异常。如果您为各种验证方案抛出RuntimeException,那么Spring将为您处理它。如果您依赖这些事实,那么您的测试可能会停止验证是否抛出了RuntimeException。

如果要使用已检查的异常(例如javax.xml.bind.ValidationException),则可以使用注释来确保它导致回滚:

@Transactional(rollbackFor = ValidationException.class)
def processCommit( ....

然后你的测试只需要检查

def ex = thrown(ValidationException)

有关详细信息,请参阅http://docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html#transaction-declarative-attransactional-settings

相关问题