Home > front end >  How do I create a detached mock with closure in Spock framework?
How do I create a detached mock with closure in Spock framework?

Time:12-16

It's good to see we can have detached mocks since Spock 1.1, especially if we want to create a mock utilities for boilerplate UT coding.

But it seems DetachedMockFactory refuses to be initialised with closure.

class MockUtils {
    def mockFactory = new DetachedMockFactory()

    IRequestContextGetter mockDefaultRequestContext() {
        return mockFactory.Mock(IRequestContextGetter) {
            tenant >> Constants.TENANT
            currencyType >> CurrencyEnum.SGD
        }
    }
}

It throws the following error:

'Mock' in 'spock.mock.DetachedMockFactory' cannot be applied to '(java.lang.Class<com.bytedance.cg.gcrm.salesplanning.common.utils.requestcontext.IRequestContextGetter>, groovy.lang.Closure)'

How do I create a detached mock with closure?

CodePudding user response:

Short answer, you can't.

Longer answer, in Spock mock interactions are actually part of the specification, not the mock object itself. So, detached mocks can't have any interactions until they get attached to a specification.

There is a way, but it is quite cumbersome. You can define you own IDefaultResponse to handle the mock interactions and customize your response that way.

import org.spockframework.util.*
import org.spockframework.mock.*
import spock.mock.*
    
interface Foo {
    String getBar()
}

class CustomResponse implements IDefaultResponse {
    public Object respond(IMockInvocation invocation) {
        'foo'
    }
}

def factory = new DetachedMockFactory()
def stub = factory.Stub(Foo, defaultResponse: new CustomResponse())
assert stub.bar == 'foo'

Try it in the Groovy Web Console

  • Related