Grails服务单元测试中如何正确Mock GORM的refresh()方法?
正确Mock GORM的refresh()方法解决单元测试失败问题
我来帮你搞定这个问题!你遇到的核心问题是对refresh()方法的类型判断错了——它是GORM的实例方法,但你之前是按静态方法来mock的,所以根本不会触发你写的mock逻辑。
错误原因拆解
你的服务代码里,UnitMeasure.get(...)确实是静态方法,所以你mockstatic.get()是正确的;但接下来的netWeightPalletUnitMeasure.refresh()是调用实例对象的方法,这时候用unitMeasureMock.demand.static.refresh()就完全不对路了,因为这个mock针对的是静态方法,而不是实例方法。
正确的Mock方式
这里有两种可靠的解决办法,你可以根据自己的测试场景选择:
方法1:调整mockFor的demand配置
用mockFor创建的mock,针对实例方法的话,直接去掉static前缀即可:
def unit = new UnitMeasure(/* 初始化你的测试属性 */) def unitMeasureMock = mockFor(UnitMeasure) // 静态get方法的mock保持不变 unitMeasureMock.demand.static.get() { Long id -> unit } // 针对实例的refresh方法做mock,不要加static unitMeasureMock.demand.refresh() { // 这里可以模拟refresh的行为:比如重置实例属性,或者空实现(如果不需要逻辑) // 比如如果需要模拟从数据库重新加载,你可以在这里给unit赋值新的属性值 }
方法2:用metaClass直接给实例动态添加方法
这种方式更灵活,尤其适合你已经有明确实例的场景:
def unit = new UnitMeasure(/* 初始化测试属性 */) // Mock静态的get方法,返回我们的测试实例 UnitMeasure.metaClass.static.get = { Long id -> unit } // 给这个特定实例添加refresh方法的实现 unit.metaClass.refresh = { -> // 模拟refresh的逻辑:比如你可以在这里模拟从数据库刷新后的状态 // 如果只是需要让方法不报错,空实现也可以 }
额外提示
在Grails单元测试中,一定要区分清楚静态方法和实例方法的mock方式。如果你的get()方法返回的是固定实例,直接给这个实例的metaClass添加方法是最直接的,能确保调用到的就是你mock的逻辑。
内容的提问来源于stack exchange,提问作者Mister B
相关产品推荐
相关产品推荐

