I have a POJO that uses a service to do something:
public class PlainOldJavaObject {
private IService service;
public String publicMethod(String x) {
return doCallService(x);
}
public String doCallService(String x) {
if(service == null) {
throw new RuntimeException("Service must not be null");
}
return service.callX(x);
}
public interface IService {
String callX(Object o);
}
}
And I have a Groovy test case:
class GTest extends GroovyTestCase {
def testInjectedMockIFace() {
def pojo = new PlainOldJavaObject( service: { callX: "very groovy" } as IService )
assert "very groovy" == pojo.publicMethod("arg")
}
def testMetaClass() {
def pojo = new PlainOldJavaObject()
pojo.metaClass.doCallService = { String s ->
"no service"
}
assert "no service" == pojo.publicMethod("arg")
}
}
The first test method, testInjectedMockIFace
works as expected: The POJO is created with a dynamic implementation of IService
. When callX
is invoked, it simply returns "very groovy". This way, the service is mocked out.
However I don't understand why the second method, testMetaClass
does not work as expected but instead throws a NullPointerException when trying to invoke callX
on the service object. I thought I had overwritten the doCallService
method with this line:
pojo.metaClass.doCallService = { String s ->
What am I doing wrong?
Thanks!
Your syntax is a tiny bit off. The problem is that pojo is a Java Object and does not have a metaClass. To intercept calls to PlainOldJavaObject's doCallService using ExpandoMetaClass:
Just replace:
pojo.metaClass.doCallService = { String s ->
"no service"
}
With:
PlainOldJavaObject.metaClass.doCallService = { String s ->
"no service"
}