2015-05-06 42 views
3

简单地说,我有以下情形:测试afterInsert Grails中

class OwnedRights { 
    static belongsTo = [comp: Competition] 

    @Transactional 
    def afterInsert() { 
     // Erroring out here. 
     Event.findAllByComp(comp).each { event -> 
      // Do something with event. 
     } 
    } 
} 

当我试图在我的单元测试保存的东西,如下列:

def ownedRights = new OwnedRights(params).save(flush: true, failOnError: true) 

我看到下面的堆栈跟踪:

java.lang.NullPointerException at org.springframework.transaction.support.TransactionTem (org.codehaus.groovy.grails.orm.support.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:85) at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java: 209) 在org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:194)

这导致我this Jira Issue这表明我没有在我的测试使用@Mock注释,但是,我嘲笑所有使用的域类:

@Mock([OwnedRights, Sport, Competition, Event]) 

这是一个包含GORM逻辑的hibernate事件的已知问题吗?

试图解决使用的metaClass

我试图重写afterInsert()beforeDelete方法:

OwnedRights.metaClass.afterInsert = null; 
OwnedRights.metaClass.beforeDelete = null; 

OwnedRights.metaClass.afterInsert = {}; 
OwnedRights.metaClass.beforeDelete = {}; 

这两者上都没有效果结果。如果我注释掉afterInsert事件,则保存完美。

回答

1

您提到@Mock。这只能在单元测试中使用,但是不应该尝试在单元测试中测试事务。

这是一个禁忌。在集成测试中测试交易。他们在允许您实现内存中的GORM实现方面所做的工作非常棒,但交易是数据库功能。你不能指望内存中的实现(由Map !!支持)像数据库一样工作。你正在测试的是单元测试的GORM实现的行为,而不是你的实际数据库。所以这个测试在现实世界中是无用的。

+0

我删除了@Transactional注解。最后,我完全删除了这些事件并做了一些重构。 – christopher

+0

那么,没有更多afterInsert?...无赖。我试图在afterInsert中测试代码,并且无法使其工作。 – Philippe

0

我用这个注解(在单元测试文件中)来解决这个问题。

@TestFor(FooBarService) 

是的,它可以测试使用单元测试服务层(但一些GORM方法可能无法使用,这取决于你的Grails版本)