如何在Spock框架中使用闭包创建detached mock?
问题描述
自Spock 1.1版本起支持detached mocks,这在创建单元测试模板工具时非常实用。但DetachedMockFactory的Mock方法无法直接通过闭包初始化,示例代码如下:
class MockUtils { def mockFactory = new DetachedMockFactory() IRequestContextGetter mockDefaultRequestContext() { return mockFactory.Mock(IRequestContextGetter) { tenant >> Constants.TENANT currencyType >> CurrencyEnum.SGD } } }
执行时抛出错误:
'Mock' in 'spock.mock.DetachedMockFactory' cannot be applied to
'(java.lang.Class<com.bytedance.cg.gcrm.salesplanning.common.utils.requestcontext.IRequestContextGetter>,
groovy.lang.Closure)'
解决方案
DetachedMockFactory的Mock()方法本身没有直接接收闭包的重载,不能像在Spock Specification块内那样直接用闭包初始化行为,推荐两种可行实现方式:
方式1:先创建Mock实例,再用闭包设置行为
先通过Mock()方法生成实例,再借助Groovy的with闭包来配置mock的交互逻辑:
class MockUtils { def mockFactory = new DetachedMockFactory() IRequestContextGetter mockDefaultRequestContext() { def mock = mockFactory.Mock(IRequestContextGetter) mock.with { tenant >> Constants.TENANT currencyType >> CurrencyEnum.SGD } return mock } }
方式2:结合Specification上下文使用重载方法
如果工具类能访问到Spock的Specification实例,可以使用Mock()的重载方法传入spec,此时就能直接用闭包初始化:
class MockUtils { def mockFactory = new DetachedMockFactory() IRequestContextGetter mockDefaultRequestContext(Specification spec) { return mockFactory.Mock(IRequestContextGetter, spec) { tenant >> Constants.TENANT currencyType >> CurrencyEnum.SGD } } }
这种方式依赖测试类的Specification上下文,适合在测试类内部的工具方法中使用。
内容的提问来源于stack exchange,提问作者Xegara
相关产品推荐
相关产品推荐

