如何将带参数的Spock Mock行为委托给真实ConfigDO实例
如何让Spock Mock的Table类方法调用委托给真实ConfigDO实例
我有一个Table类,其getDataFromTable方法接收一个参数,底层会依次委托给TableConfig::getTableData和ConfigDO::getTableMap。现在需要实现:当Mock Table(或其依赖的TableConfig)时,让带参数的getDataFromTable调用最终委托给真实的ConfigDO实例,即期望效果为:
getDataFromTable(argument) >> configDo.getTableDataMap().get(argument)
涉及类代码
Table类
package com.place.core; import org.springframework.stereotype.Component; import com.place.configuration.TableConfig; @Component public class Table { private final TableConfig tableConfig; public Table(TableConfig config) { this.tableConfig = config; } public String getDataFromTable(String tableName) { return tableConfig.getTableData(tableName); } }
TableConfig类
package com.place.configuration; import com.place.representation.ConfigDO; import org.springframework.context.annotation.Configuration; @Configuration public class TableConfig { private final ConfigDO configDo; public TableConfig(ConfigDO config) { this.configDo = config; } public String getTableData(String tableName) { return configDo.getTableMap().get(tableName); } }
ConfigDO类
package com.place.representation; import lombok.Data; import java.util.Map; @Data public class ConfigDO { private final Map<String, String> tableDataMap; }
当前测试代码雏形:
class TableTest extends Specification { def configDo = new ConfigDO() def mockTableConfig = Mock(TableConfig) { // 想要实现:将TableConfig::getTableData的参数传递给Map::get调用 getTableData(argument) >> configDo.getTableDataMap().get(argument) } }
解决方案
在Spock中,可以通过参数捕获闭包实现将Mock方法的参数传递给真实实例的调用,以下是两种常用实现方式:
方式1:Mock TableConfig并转发参数
修改TableConfig的Mock定义,用闭包接收调用参数,再转发给真实ConfigDO的逻辑:
class TableTest extends Specification { // 初始化带测试数据的ConfigDO实例 def testTableData = ["user": "user_table", "order": "order_table"] def configDo = new ConfigDO(tableDataMap: testTableData) def "测试getDataFromTable委托给真实ConfigDO"() { given: // Mock TableConfig,将getTableData的参数转发给configDo def mockTableConfig = Mock(TableConfig) { getTableData(_) >> { String tableName -> configDo.getTableDataMap().get(tableName) } } // 初始化真实Table类,注入Mock的TableConfig def table = new Table(mockTableConfig) expect: table.getDataFromTable("user") == "user_table" table.getDataFromTable("order") == "order_table" table.getDataFromTable("nonexist") == null } }
方式2:直接Mock Table类并转发参数
如果需要直接Mock Table类,同样可以用闭包参数转发:
class TableTest extends Specification { def testTableData = ["user": "user_table", "order": "order_table"] def configDo = new ConfigDO(tableDataMap: testTableData) def "测试Mock Table类时委托给真实ConfigDO"() { given: def mockTable = Mock(Table) { getDataFromTable(_) >> { String tableName -> configDo.getTableDataMap().get(tableName) } } expect: mockTable.getDataFromTable("user") == "user_table" } }
关键说明
_是Spock的参数匹配器,表示匹配任意参数;若需限制参数范围,可使用eq("user")等精确匹配器。- 闭包
{ String tableName -> ... }会接收Mock方法被调用时传入的真实参数,随后即可用该参数调用ConfigDO的真实逻辑。 - 需提前给
ConfigDO的tableDataMap初始化测试数据,避免空指针异常。
内容的提问来源于stack exchange,提问作者spartanhooah
相关产品推荐
相关产品推荐

