4

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

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

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

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

4

3 回答 3

3

为了提高性能,Grails 直接使用反射和缓存方法句柄来调用事件,而不是 Groovy 的元层。原因是,如果您要保存数百个域实例,如果 Grails 必须为每个事件都通过 Groovy 的元层,则会严重影响性能。

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

于 2014-06-20T07:24:02.307 回答
1

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

于 2012-12-29T10:20:24.683 回答
0

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

于 2017-10-06T22:59:06.167 回答