GroovySpock方法的经典单元测试



我有一个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块,因为这个测试用例似乎与给定系统上的刺激/响应不太一致。但如果您愿意,也可以使用许多whenthen交替块:

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似乎使这一点不像过去那么重要。

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

最新更新