Reputation: 219
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')
}
}
Upvotes: 1
Views: 231
Reputation: 50245
Yes, don't mock SomethingElse
. Use ExpandoMetaClass
instead.
void testSomething() {
SomethingElse.metaClass.someMethod = {int num, String str, Map another,
List param ->
println 'worked'
}
controller.obj = new SomethingElse()
controller.underTest()
}
with the price of loosing the mock control.
A roundabout way would be to mock otherCall()
as well
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()
}
This way you can verify the mock control. But I am still skeptical about using mock objects and MethodClosure
together.
Upvotes: 1