使用Groovy MetaClass覆盖方法 [英] Using Groovy MetaClass to overwrite Methods
问题描述
我有一个使用服务来执行某些操作的POJO:
public class PlainOldJavaObject {
私人IService服务;
public String publicMethod(String x){
return doCallService(x);
$ b $ public String doCallService(String x){
if(service == null){
throw new RuntimeException(Service must not null);
}
return service.callX(x);
}
public interface IService {
String callX(Object o);
$ b我有一个Groovy测试用例: class GTest扩展GroovyTestCase {
def testInjectedMockIFace(){
def pojo = new PlainOldJavaObject :{callX:very groovy} as IService)
assertvery groovy== pojo.publicMethod(arg)
}
def testMetaClass(){
def pojo = new PlainOldJavaObject()
pojo.metaClass.doCallService = {String s - >
no service
}
assertno service== pojo.publicMethod(arg)
}
}
$ c第一个测试方法 testInjectedMockIFace
按预期工作:POJO创建为动态实现 IService
。当调用 callX
时,它只会返回非常常见。这样,服务就被嘲笑了。然而,我不明白为什么第二个方法 testMetaClass
不能按预期工作,而是抛出一个NullPointerException当试图在服务对象上调用 callX
时。我认为我已经用这一行覆盖了 doCallService
方法:
pojo .metaClass.doCallService = {String s - >
我做错了什么?
谢谢!
解决方案您的语法稍微偏离了一点。问题是pojo是一个Java对象,并没有metaClass。拦截使用ExpandoMetaClass调用PlainOldJavaObject的doCallService:
只需替换:
pojo.metaClass.doCallService = {String s - >
无服务
}
与:
PlainOldJavaObject.metaClass.doCallService = {String s - >
无服务
}
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"
}
这篇关于使用Groovy MetaClass覆盖方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!