Spock中如何重置方法mock并覆盖已有的mock配置?
Spock Mock配置覆盖方案
问题根因
Spock默认对同一个Mock对象的同方法Stub规则采用追加模式,先在setup()中声明的规则优先级高于测试用例内后声明的规则,因此你当前的写法无法覆盖默认配置。
可用解决方案
方案1:手动重置Mock所有拦截规则
使用Spock内置的MockUtil工具直接清空Mock对象的所有已有配置、调用记录,再声明新的Stub规则即可:
import spock.mock.MockUtil // Spock 2.x导入路径,1.x为org.spockframework.mock.MockUtil def 'exercise missed user processing'() { given: '清空原有Mock规则' MockUtil.reset(authProvider) and: '配置新的返回值' authProvider.authenticationPrincipal >> emptyUser ... }
- 适用场景:需要完全重置Mock状态,不依赖之前的Stub配置和调用记录的情况。
方案2:动态响应式Stub
在setup()中使用闭包声明Stub返回值,绑定可修改的公共变量,需要覆盖时直接修改变量值即可,无需重置Mock:
// 测试类内部定义可变的默认返回值变量 def defaultPrincipal = random(authUserDetails) def setup() { // 用闭包绑定变量,每次调用方法都会取变量最新值 authProvider.authenticationPrincipal >> { defaultPrincipal } } def 'exercise missed user processing'() { given: '修改返回值变量' defaultPrincipal = emptyUser ... }
- 适用场景:不需要清空调用记录,仅需要修改返回值的场景,性能优于方案1。
方案3:setup内按用例条件配置
在setup()中获取当前执行的测试用例名称,按条件配置不同的返回值:
def setup() { def currentTestName = specificationContext.currentIteration.name if (currentTestName == 'exercise missed user processing') { authProvider.authenticationPrincipal >> emptyUser } else { authProvider.authenticationPrincipal >> random(authUserDetails) } }
- 适用场景:需要特殊配置的测试用例数量极少的场景,不用修改单个用例逻辑。
内容的提问来源于stack exchange,提问作者Mr.Ustiik
相关产品推荐
相关产品推荐

