Spock中复用通用闭包的实现方案问询
提取Spock中重复闭包实现复用的几种方法
当然可以!重复的闭包逻辑完全可以提取出来复用,既减少冗余代码,又方便后续统一维护。下面给你几种实用的实现方案:
1. 提取为测试类的私有方法
这是最直接的方式,把闭包逻辑封装成普通方法,然后在交互定义里通过方法引用调用:
class YourSpec extends Specification { // 把复用逻辑封装成私有方法 private Something getDaoResponse(Something smth, String value) { return createSomething(smth).withValue(value).build() } def "test case 1"() { given: // 测试前置准备 when: // 执行待测试操作 then: 1 * dao.getByValue(Something.ONE, _ as String) >> this.&getDaoResponse } def "test case 2"() { given: // 另一个测试的前置准备 when: // 执行待测试操作 then: 1 * dao.getByValue(Something.TWO, _ as String) >> this.&getDaoResponse } }
这里用this.&getDaoResponse把方法转换成闭包,Spock会自动把mock方法的参数传递给这个方法,完美匹配原逻辑。
2. 提取为静态闭包常量
如果这个mock响应逻辑需要在多个测试类中复用,可以把它定义成静态闭包,放在工具类或者测试基类里:
// 通用测试工具类 class SpockMockHelpers { static final Closure daoGetByValueResponse = { Something smth, String value -> createSomething(smth).withValue(value).build() } } // 在测试类中直接引用 class YourSpec extends Specification { def "test case"() { then: 1 * dao.getByValue(Something.ONE, _ as String) >> SpockMockHelpers.daoGetByValueResponse } }
这种方式适合跨类复用的场景,把通用的mock响应逻辑集中管理,修改时只需改一处即可。
3. 封装到测试基类中
如果你的项目有大量类似的DAO mock需求,可以把这类逻辑封装到抽象基类里,让所有相关测试类继承:
abstract class BaseDaoSpec extends Specification { protected Closure getDaoValueResponse() { return { Something smth, String value -> createSomething(smth).withValue(value).build() } } } // 测试类继承基类后直接使用 class YourSpec extends BaseDaoSpec { def "test case"() { then: 1 * dao.getByValue(Something.ONE, _ as String) >> getDaoValueResponse() } }
这种方式能让所有继承基类的测试类直接复用该逻辑,保持项目测试代码的风格一致。
小提醒
- 要确保提取后的方法/闭包参数列表,和mock方法的参数严格匹配,否则会出现参数不匹配的错误。
- 如果
createSomething也是测试通用方法,也可以一起封装到工具类或基类中,进一步减少冗余。
内容的提问来源于stack exchange,提问作者Shadov
相关产品推荐
相关产品推荐

