将模拟代码重构为另一个类会导致Spock测试失败

时间:2014-03-13 02:36:27

标签: unit-testing groovy spock

我有一个Groovy / Spock单元测试如下:

public class ThingUnitTest extends Specification {

  def "doing a thing delegates to the context"() {
    given : def thing = createThing()
    when  : thing.doThing()
    then  : 1 * thing.context.doThing()
  }

  def createThing() {
    def thing = new ThingImpl()
    thing.context = createThingContext()
    return thing
  }

  def createThingContext() {
    def context = Spy(ThingContext)
    context.foo = Mock(Foo)
    context.bar = Mock(Bar)
    return context
  }
} 

此测试将毫无问题地运行。但事实证明我还有其他需要ThingContext的测试,所以我想将createThingContext代码移到一个公共类中:

public class ThingContextFactory extends Specification {
  def createThingContext() {
    def context = Spy(ThingContext)
    context.foo = Mock(Foo)
    context.bar = Mock(Bar)
    return context
  }
} 

然后按如下方式编写单元测试:

public class ThingUnitTest extends Specification {
  ...
  def createThingContext() {
    return new ThingContextFactory().createThingContext()
  }
} 

但是现在测试失败了,断言1 * thing.context.doThing()失败,没有互动。

我也尝试了以下内容:

public class ThingContextFactory {
  def createThingContext() {
    def mocking = new MockingApi()
    def context = mocking.Spy(ThingContext)
    context.foo = mocking.Mock(Foo)
    context.bar = mocking.Mock(Bar)
    return context
  }

但现在测试失败了MockingApi.invalidMockCreation ... InvalidSpec

请注意,我不想在这里使用继承,而是将常见的模拟代码移动到帮助程序类中。但是当我这样做时,我的spock测试失败了。

有没有一些正确的方法来重构Spock模拟代码?

1 个答案:

答案 0 :(得分:1)

从Spock 0.7开始,模拟对象只能在使用它们的测试类或其超类中创建。这可能会在下一个版本中发生变化。

相关问题