Don Branson
Don Branson

Reputation: 13707

Is it possible to mock a method in a Groovy class-under-test such that other methods within the class will use the mocked version?

For example:

class CutService {

    String delegateToSelf(){
        aMethod()
    }

    String aMethod(){
        "real groovy value from CUT"
    }
}

I've tried a variety of approaches, including:

@TestFor(CutService)
class CutServiceSpec extends Specification {

    def expectedValue = "expected value"

    void "test mocking CUT method using MockFor"() {
        given:
        MockFor mockCutService = new MockFor(CutService)
        mockCutService.ignore.aMethod {expectedValue}
        def cutServiceProxy = mockCutService.proxyDelegateInstance()

        when:
        String actualValue = null
        mockCutService.use {
            actualValue = cutServiceProxy.delegateToSelf()
        }

        then:
        expectedValue == actualValue
    }
}

Which gives:

| Failure:  test mocking CUT method using MockFor(com...CutServiceSpec)
|  junit.framework.AssertionFailedError: No more calls to 'delegateToSelf' expected at this point. End of demands.
        at com...CutServiceSpec.test mocking CUT method using MockFor_closure4(CutServiceSpec.groovy:45)
at com...CutServiceSpec.test mocking CUT method using MockFor(CutServiceSpec.groovy:44)

Upvotes: 2

Views: 1385

Answers (1)

Don Branson
Don Branson

Reputation: 13707

Using metaClass appears to do what I want:

void "test mocking CUT method using metaClass"() {
    given:
    service.metaClass.aMethod = { expectedValue }

    when:
    String actualValue = service.delegateToSelf()

    then:
    expectedValue == actualValue
}

This test runs green.

Upvotes: 1

Related Questions