覆盖Grails GORM域类上的事件关闭以进行单元测试

时间:2012-12-28 19:37:06

标签: unit-testing grails groovy gorm expandometaclass

我正在开发一个新的Grails项目,并且最近注意到Spring Security Core生成的User类中的默认约定现在通过beforeInsert / Update事件自动编码密码。这是一种很好,干净,干燥的编码方式,也让人无法忘记这样做。

但是,现在在尝试编写一些使用所述User类的单元测试时,我发现我要么必须模拟springSecurityService(由于编码),或者更优选(并且干净利落),我会只需用一个什么也不做的覆盖beforeInsert / Update闭包。通常在Groovy中,可以使用ExpandoMetaClass覆盖方法,ala ...

User.metaClass.beforeInsert = { /* do nothing */ }  

...但我发现在创建和保存新用户时会继续调用原始的beforeInsert。这反过来导致我的单元测试爆炸。对我来说,解决这个问题并模拟服务是微不足道的,但上面的 应该可以工作 。我错过了什么吗?与GORM的事件关闭有什么不同,我没有接受?

3 个答案:

答案 0 :(得分:3)

为了提高性能,Grails直接使用caches方法句柄来调用事件,而不是Groovy的元层。原因是,如果你要保存数百个域实例,那么如果Grails必须为每个事件通过Groovy的元层,那么它会严重损害性能。

有很多方法可以解决这个问题,例如定义你自己的User类,它根据你的测试设置的系统/环境属性来禁用事件,但目前没有办法通过元编程覆盖这些方法。

答案 1 :(得分:1)

beforeInsert闭包实际上不仅是像toString()或save()这样的方法,而且它是Gorm支持的预定义事件。覆盖该方法不会阻止Gorm触发PreInsert事件,这会导致原始进程。

答案 2 :(得分:0)

如有必要,您可以使用私有方法替换beforeInsert中的代码,然后覆盖私有方法