Spock:数据管道和变量分配
Spock: Data Pipes, and Variable Assignments
来自 Spock documentation:
Data tables, data pipes, and variable assignments can be combined as needed:
...
where:
a | _
3 | _
7 | _
0 | _
b << [5, 0, 0]
c = a > b ? a : b
这个简单的示例为 y
生成 MissingPropertyException
。
def test() {
expect:
x == 42
where:
y = 12
x << [y + 30, 54 - y]
}
这个例子有什么问题?
我认为赋值 y=12
在 where 块中是不允许的。
例如,这个版本有效,两个测试 运行 符合预期:
class SampleTest extends Specification {
@Unroll
def "test"() {
expect:
x == 42
where:
x << [12 + 30, 54 - 12]
}
}
如果您绝对需要作业,以下方法也适用:
class SampleTest extends Specification {
@Unroll
def "test"() {
expect:
x == 42
where:
x << myfunc()
}
def myfunc() {
def y = 12
[y + 30, 54 - y]
}
}
你不能那样混合数据管道和变量赋值。让我们看一下源代码。您可以在第 49 行的 org.spockframework.runtime.ParameterizedSpecRunner
class 中放置一个断点,并使用调试器进行测试 运行。您会看到 currentFeature
包含两个名称为 y
和 x
的参数:
您还会注意到变量名 x
定义了一个 dataProvider
:
此数据提供程序存在是因为我们已将 x
定义为数据管道,因此它必须遍历变量列表并在数据管道的上下文中对其进行评估。在此上下文中,它期望 y
变量也被定义为数据管道,因此它可以采用与同一索引关联的值。
如果您将 where:
定义为:
where:
y << [12, 12]
x << [y + 30, 54 - y]
您的测试会成功,因为现在 y
变量作为数据提供者存在,并且 x
的评估值使用第二个数据提供者访问 y
的值。
如何将变量赋值与数据管道相结合?
考虑以下示例:
@Unroll
def "variable assignment example"() {
expect:
x == 42
and:
c
where:
y << [12, 12]
x << [y + 30, 54 - y]
c = y < x
}
在这种情况下,变量 c
为数据管道 y
和 x
中的每个元素计算两次。当第一次展开发生时 y = 12
、x = y + 30 => 12 + 30 => 42
和 c
的计算结果为 true
,因为 y<x
。当第二次展开发生时,12
值再次分配给 y
,x
计算为 42
(54 - y => 54 - 12 => 42
),c
计算为 true
再次。
结论
我看到它可能看起来很简单 y = 12
变量赋值应该由数据管道评估发现。不幸的是,它不是那样工作的。评估数据管道时,它只能使用来自其他数据管道的值,并且在此上下文中看不到任何变量赋值。
来自 Spock documentation:
Data tables, data pipes, and variable assignments can be combined as needed:
... where: a | _ 3 | _ 7 | _ 0 | _ b << [5, 0, 0] c = a > b ? a : b
这个简单的示例为 y
生成 MissingPropertyException
。
def test() {
expect:
x == 42
where:
y = 12
x << [y + 30, 54 - y]
}
这个例子有什么问题?
我认为赋值 y=12
在 where 块中是不允许的。
例如,这个版本有效,两个测试 运行 符合预期:
class SampleTest extends Specification {
@Unroll
def "test"() {
expect:
x == 42
where:
x << [12 + 30, 54 - 12]
}
}
如果您绝对需要作业,以下方法也适用:
class SampleTest extends Specification {
@Unroll
def "test"() {
expect:
x == 42
where:
x << myfunc()
}
def myfunc() {
def y = 12
[y + 30, 54 - y]
}
}
你不能那样混合数据管道和变量赋值。让我们看一下源代码。您可以在第 49 行的 org.spockframework.runtime.ParameterizedSpecRunner
class 中放置一个断点,并使用调试器进行测试 运行。您会看到 currentFeature
包含两个名称为 y
和 x
的参数:
您还会注意到变量名 x
定义了一个 dataProvider
:
此数据提供程序存在是因为我们已将 x
定义为数据管道,因此它必须遍历变量列表并在数据管道的上下文中对其进行评估。在此上下文中,它期望 y
变量也被定义为数据管道,因此它可以采用与同一索引关联的值。
如果您将 where:
定义为:
where:
y << [12, 12]
x << [y + 30, 54 - y]
您的测试会成功,因为现在 y
变量作为数据提供者存在,并且 x
的评估值使用第二个数据提供者访问 y
的值。
如何将变量赋值与数据管道相结合?
考虑以下示例:
@Unroll
def "variable assignment example"() {
expect:
x == 42
and:
c
where:
y << [12, 12]
x << [y + 30, 54 - y]
c = y < x
}
在这种情况下,变量 c
为数据管道 y
和 x
中的每个元素计算两次。当第一次展开发生时 y = 12
、x = y + 30 => 12 + 30 => 42
和 c
的计算结果为 true
,因为 y<x
。当第二次展开发生时,12
值再次分配给 y
,x
计算为 42
(54 - y => 54 - 12 => 42
),c
计算为 true
再次。
结论
我看到它可能看起来很简单 y = 12
变量赋值应该由数据管道评估发现。不幸的是,它不是那样工作的。评估数据管道时,它只能使用来自其他数据管道的值,并且在此上下文中看不到任何变量赋值。