1

我有一个 Groovy Spock 方法,它具有以下模式:

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()is 实际上c.fieldLevel3 instanceof A,所以如果该字段无效,我将无法继续。

4

2 回答 2

4

单元测试的“经典”方式是保持测试单一。也就是说,每次测试都测试一件事,在这个例子中似乎不是这样。

但是,话虽如此,您可以在一个expect块中的所有设置代码之后将所有断言分组到一个setup块中:

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()asvalid并直接在辅助对象上调用该方法来缩短断言。

另外,我没有使用通常的when/thenSpock 块,因为这个测试用例似乎与给定系统上的刺激/响应不太一致。但是,如果您愿意,也可以使用许多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
}
于 2012-09-11T21:03:41.170 回答
1

不知道您为什么不接受上面的答案,看起来还不错。

作为一个小区别,您还可以执行以下操作:

def "My test of creating an A"() {
    when: 
        def a = createA()
    then: 
        a.fieldLevel1.isValid()
        a.fieldLevel1.fieldLevel2.isValid()
        a.fieldLevel1.fieldLevel2.fieldLevel3.isValid()
}

您是否“喜欢”这取决于您遵循得墨忒耳的“法则”的程度——Groovy 似乎使这一点不像过去那么重要。

如果实际底层对象的复杂性使得这不是验证它们的有效方法,那么它们可能值得拥有自己的单元测试。

于 2014-03-25T19:45:23.593 回答