Question

I am trying to use ia mocked object in the table of a "where" clause. Basically something like this:

def "my test"(){

    given:
    InjectedObject1 inj1 = Mock()
    InjectedObject2 inj2 = Mock()
    SystemUnderTest system = new System(inj1, inj2)
    MockedObject mocked = Mock()

    inj1.someMethod() >> list  // this will be a list of MockedObject

    when:
    system.execute()

    then:
    n * inj2.someOtherMethod()

    where:
    list             | n
    [mocked]         | 0
    [mocked, mocked] | 1
}

This doesn't work because the "where" clause is executed before the "given" clause, so mocked doesn't exist yet when it is first referenced. How do I overcome this? mocked in used only is this test so I'd like to avoid creating it outside of this method.

Note that this is a simplified example, there are actually more interactions, and other columns in the table that have an influence on n - which makes the table syntax very handy.

Was it helpful?

Solution

You can refactor the method to something like:

...
inj1.someMethod() >> [mocked] * numReturned
...
then:
numCalled * inj2.someOtherMethod()

where:
numReturned | numCalled
1           | 0
2           | 1

In other words, specify (just) the parts in the where-block and assemble them in the method body. This is a common solution.

Usually, another solution is to shuffle the objects to be used in the where-block into @Shared fields. The 'too big scope' problem can be mitigated by having multiple small specs in the same file. However, this solution won't work for mocks because mocks can't be @Shared.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top