是否可以在 Groovy class 测试中模拟一个方法,以便 class 中的其他方法将使用模拟版本?

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?

例如:

class CutService {

    String delegateToSelf(){
        aMethod()
    }

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

我尝试了多种方法,包括:

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

给出:

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

使用元类似乎可以满足我的要求:

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

    when:
    String actualValue = service.delegateToSelf()

    then:
    expectedValue == actualValue
}

此测试运行绿色。