I have a class Table
with a method getDataFromTable
which takes one argument. Under the hood, Table::getDataFromTable
just delegates to TableConfig::getTableData
which further delegates to ConfigDO::getTableMap. How can I have my Spock Mock of
Tabledelegate this method call with its argument to the real instance of
ConfigDO`? I.e. I want
getDataFromTable(argument) >> configDo.getTableDataMap().get(argument)
Classes involved:
package com.place.core;
import org.springframework.stereotyp.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);
}
}
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);
}
}
package com.place.representation;
import lombok.Data;
import java.util.Map;
@Data
public class ConfigDO {
private final Map<String, String> tableDataMap;
}
Minimal spec:
class TableTest extends Specification {
def configDo = new ConfigDO()
def mockTableConfig = Mock(TableConfig) {
// What I feel like I'd like to do: take the argument from TableConfig::getTableData and pass it to the Map::get call
getTableData(argument) >> configDo.getTableDataMap().get(argument)
}
}
I recreated simplified Groovy versions of your Java classes without any references to Spring or Lombok, because the latter are irrelevant for your question.
getDataFromTable
, which does not exist in TableConfig
. You cannot stub a Table
method in TableConfig
. Please be more careful to actually stub methods which really exist in the class to be mocked/stubbed.package de.scrum_master.stackoverflow.q76038114
import spock.lang.Specification
class TableTest extends Specification {
def configDo = new ConfigDO()
def mockTableConfig = Mock(TableConfig) {
getTableData(_) >> { args -> configDo.tableDataMap[args[0]] }
}
def test() {
given:
def table = new Table(mockTableConfig)
expect:
table.getDataFromTable('foo') == 'Hello world!'
table.getDataFromTable('bar') == 'These are just test data.'
}
}
package de.scrum_master.stackoverflow.q76038114
class Table {
private final TableConfig tableConfig
Table(TableConfig config) {
this.tableConfig = config
}
String getDataFromTable(String tableName) {
return tableConfig.getTableData(tableName)
}
}
package de.scrum_master.stackoverflow.q76038114
class TableConfig {
private final ConfigDO configDo
TableConfig(ConfigDO config) {
this.configDo = config
}
String getTableData(String tableName) {
return configDo.getTableMap().get(tableName)
}
}
package de.scrum_master.stackoverflow.q76038114
class ConfigDO {
private final Map<String, String> tableDataMap = [
foo: 'Hello world!',
bar: 'These are just test data.'
]
Map<String, String> getTableDataMap() {
return tableDataMap
}
}
Try it in the Groovy Web Console.