我正在处理一个新的 Grails 项目,最近注意到 Spring Security Core 生成的用户类中的默认约定现在通过 beforeInsert/Update 事件自动编码密码。这是一种很好的、干净的、DRY 的编码方式,并且不会忘记这样做。
但是,现在当尝试编写一些使用所述 User 类的单元测试时,我发现我要么必须模拟 springSecurityService(由于编码),要么更优选(并且干净利落地),我会只需用一个什么也不做的闭包覆盖 beforeInsert/Update 闭包。通常在 Groovy 中,可以使用 ExpandoMetaClass 重写方法,等等......
User.metaClass.beforeInsert = { /* do nothing */ }
...但我发现在创建和保存新用户时继续调用原始 beforeInsert。这反过来又导致我的单元测试失败。解决这个问题并模拟服务对我来说是微不足道的,但上面的应该可行。我错过了什么吗?我没有注意到 GORM 的事件关闭有什么不同吗?
最佳答案
为了提高性能,Grails 直接使用反射和缓存方法句柄来调用事件,而不是 Groovy 的元层。原因是,如果您要保存数百个域实例,如果 Grails 必须为每个事件都经过 Groovy 的元层,这会严重损害性能。
有很多方法可以解决这个问题,例如定义您自己的 User
类,该类根据您的测试设置的系统/环境属性禁用事件等。但是目前没有办法通过元编程。
关于unit-testing - 覆盖 Grails GORM 域类上的事件关闭以进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14074761/