简单地说,我有以下情况:
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 在org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:130) 在org.codehaus.groovy.grails.orm.support.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:85) 在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事件,则保存工作正常。
答案 0 :(得分:1)
你提到@Mock。这只能用于单元测试,但是你不应该尝试在单元测试中测试事务。
这是禁忌。在集成测试中测试事务。他们在允许您进行内存中GORM实现方面所做的工作非常棒,但事务是数据库功能。您不能期望内存实现(由Map支持!!)的行为就像数据库一样。您正在测试的是GORM实现单元测试的行为,而不是您的实际数据库。因此,测试在现实世界中毫无用处。
答案 1 :(得分:0)
我使用此注释(在单元测试文件中)来解决问题。
@TestFor(FooBarService)
是的,可以使用单元测试来测试服务层(但是根据您的Grails版本,某些GORM方法可能不可用)