Pirax
Pirax

Reputation: 146

Using spocks method counter on mocks out of compositions?

I have an issue with creating test data with spock framework. To follow "composition over inheritance", I have a class to create testdata for my unit tests. As a simple snipped it looks like this:

class TestData extends Specification{

    Foo createFoo(){
        GroovyMock(Foo){
            doSomething() >> "MOCKED!"
        }
    }
}

When I write a Test, i like to test, if and how often the method has been invoked. Like this

def "simple test"(){
    given:
    TestData testData = new TestData()
    Foo foo = testData.createFoo()

    when:
    println foo.doSomething()

    then:
    1 * foo.doSomething()
}

I know, this test doesn't makes sense. It's just for illustriating the behavior.

I would expect a "green result" of that test, since doSomething() has been invoked 1 time. But test result is red:

Too few invocations for:

1 * foo.doSomething()   (0 invocations)
[...]

When i mock Foo directly, everything works fine :

def "simple test"(){
    given:
    Foo foo = GroovyMock(Foo){
        doSomething() >> "MOCKED!"
    }

    when:
    println foo.doSomething()

    then:
    1 * foo.doSomething()
}

Anyone has an idea how to treat this without deriving my testclass from TestData?

Btw. I used the stub returning "MOCKED!" to show, the mock works. But its not "overwritten" or whatever it is called, when testData created the mock.

Upvotes: 0

Views: 49

Answers (1)

Leonard Brünings
Leonard Brünings

Reputation: 13222

Mocks interactions must be defined inside the Specification that uses them. Importing mocks from other sources like

TestData testData = new TestData()
Foo foo = testData.createFoo()

is not supported.

While it is possible to create mocks outside of a Specification and attach them later on, it is not possible to define interactions outside of a Specification.

Upvotes: 1

Related Questions