1

Code below. I would like to use the obj.&method thing to pass around a reference to it. However, when trying to test that, mocking it doesn't work. Is there something in the test I can do to make it work?

The result of running the test is it throws the exception "should not get here".

import grails.test.mixin.TestFor

@TestFor(SomeController)
class SomeControllerTest {
    void testSomething() {
        def control = mockFor(SomethingElse)
        control.demand.someMethod(1) { int num, String str, Map another, List param ->
            println 'worked'
        }
        controller.obj = control.createMock()

        controller.underTest()

        control.verify()
    }
}

class SomeController {
    SomethingElse obj

    void underTest() {
        otherCall(obj.&someMethod) // **
    }

    void otherCall(toRun) {
        String result = toRun(1, 'blah', null, null) // ** doesn't call mock here
    }
}

class SomethingElse {
    String someMethod(int num, String str, Map another, List param) {
        throw new RuntimeException('should not get here')
    }
}
4

1 回答 1

1

是的,不要嘲笑SomethingElse。改为使用ExpandoMetaClass

void testSomething() {
    SomethingElse.metaClass.someMethod = {int num, String str, Map another, 
                                             List param ->
        println 'worked'
    }

    controller.obj = new SomethingElse()

    controller.underTest()
}

失去模拟控制的代价。

一种迂回的方式也是otherCall()模拟

void testSomething() {
    def control = mockFor(SomethingElse)
    control.demand.someMethod(1) { int num, String str, Map another, 
                                        List param ->
        println 'worked'
    }

    def obj = control.createMock()

    controller.metaClass.otherCall = {Closure clos -> 
        delegate.obj.someMethod(1, 'blah', null, null)
    }

    controller.obj = obj
    controller.underTest()
    control.verify()
}

这样您就可以验证模拟控件。但我仍然对使用模拟对象和MethodClosure一起使用持怀疑态度。

于 2013-10-01T22:07:28.767 回答