我不知道functionalUtils 和csvFile 是如何定义的。我假设前者是@Shared 变量(否则不能在where: 块中使用),后者是在where: 块内定义的数据变量。
我正在使用multi-variable data pipes,这是一个已经存在几年的功能,可以选择与multi-variable assignment(Spock 2.0-M3 中引入的一个功能)结合使用。这个向后兼容的测试版本可以在 Spock 1.3 和 2.0 中运行:
package de.scrum_master.q66485337
import spock.lang.Shared
import spock.lang.Specification
import spock.lang.Unroll
class MultipleCompaniesCSVTest extends Specification {
@Shared
def functionalUtils = new FunctionalUtils()
@Unroll
def "company #company, row #row"() {
expect:
csvFile.startsWith(company)
firstName.contains("-$company-")
lastName.contains("-$company-")
firstName.endsWith("-$id")
lastName.endsWith("-$id")
where:
[company, csvFile, row] << getRecordsForCompanies("A", "B", "C", "D")
id = row[0]; firstName = row[1]; lastName = row[2]
// Since Spock 2.0-M3 you can simplify to:
// (id, firstName, lastName) = row
}
private List<List> getRecordsForCompanies(String... companies) {
def records = []
companies.each { company ->
def csvFile = "${company}.csv"
functionalUtils.getRecordsFromCsv(csvFile).each { row ->
records.add([company, csvFile, row])
}
}
records
}
static class FunctionalUtils {
def getRecordsFromCsv(String csvFile) {
def company = csvFile.replaceFirst("[.]csv\$", "")
// Emulate company-specific CSV file, creating some records
(1..3).collect { id -> [id, "John-$company-$id", "Doe-$company-$id"] }
}
}
}
从 2.0-M3 开始,您可以根据需要将 id = row[0]; firstName = row[1]; lastName = row[2] 简化为 (id, firstName, lastName) = row。
顺便说一句,在 Spock 2 中,展开是默认设置,因此您也可以在此处省略 @Unroll。
免责声明:可能有一种更实用的常规方法来创建数据管道的值,而无需在闭包或辅助方法中强制修改本地数据结构的状态,然后返回最终结果。也许还有一些额外的迭代方法,类似于permutations() 或combinations()。如果是这样,我还没有找到它,不是 Groovy 专家。