John Q Citizen
John Q Citizen

Reputation: 3258

Refactoring mocking code into another class causes Spock tests to fail

I have a Groovy/Spock unit test as follows:

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
  }
} 

This test will run without problems. However it turns out that I have other tests that need a ThingContext, so I want to move the createThingContext code into a common class:

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

and then write my unit tests as follows:

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

But now the test fails, with the assertion 1 * thing.context.doThing() failing with zero interactions.

I also tried the following:

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
  }

But now the tests fail with MockingApi.invalidMockCreation ... InvalidSpec

Note that I do not want to use inheritance here, but move common mocking code into helper classes. But when I do this my spock tests fail.

Is there some proper way to refactor Spock mocking code?

Upvotes: 2

Views: 448

Answers (1)

Peter Niederwieser
Peter Niederwieser

Reputation: 123890

As of Spock 0.7, mock objects can only be created in the test class that uses them, or a superclass thereof. This might change in the next version.

Upvotes: 2

Related Questions