我有一个GroovySpock方法,它具有以下模式:
def "My test"() {
def a = createA();
assert a.fieldLevel1.isValid()
def b = a.fieldLevel1
assert b.fieldLevel2.isValid()
def c = b.fieldLevel2
assert c.fieldLevel3.isValid()
...
}
正如您所看到的,由于断言和变量定义混合在一起,很难在块上打破它。编写这种测试的"spock"方法是什么?
更新:
测试具有以下结构,因为c.fieldLevel3.isValid()
实际上是c.fieldLevel3 instanceof A
,所以如果字段无效,我就无法继续。
单元测试的"经典"方法是保持测试的单一性。也就是说,每个测试测试一件事,本例中的情况似乎并非如此。
尽管如此,您可以在setup
块中的所有设置代码之后,将expect
块中的全部断言分组:
def "My test"() {
setup:
def b = createA().fieldLevel1
def c = b.fieldLevel2
def d = c.fieldLevel3
expect:
b.valid
c.valid
d.valid
}
注意,我使用Groovy的好东西将isValid()
作为valid
访问,并直接在辅助对象上调用该方法,从而缩短了断言。
此外,我还没有使用通常的when/then
Spock块,因为这个测试用例似乎与给定系统上的刺激/响应不太一致。但如果您愿意,也可以使用许多when
和then
交替块:
def "My test"() {
when: def b = createA().fieldLevel1
then: b.valid
when: def c = b.fieldLevel2
then: c.valid
when: def d = c.fieldLevel3
then: d.valid
}
不知道你为什么不接受上面的答案,它看起来很好。
作为一个小区别,你也可以做:
def "My test of creating an A"() {
when:
def a = createA()
then:
a.fieldLevel1.isValid()
a.fieldLevel1.fieldLevel2.isValid()
a.fieldLevel1.fieldLevel2.fieldLevel3.isValid()
}
你是否"喜欢"这取决于你遵循Demeter的"定律"的程度——Groovy似乎使这一点不像过去那么重要。
如果实际底层对象的复杂性使得这不是验证它们的有效方法,那么它们可能应该拥有自己的单元测试。