使用Groovy MetaClass覆盖方法 [英] Using Groovy MetaClass to overwrite Methods

查看:356
本文介绍了使用Groovy MetaClass覆盖方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用服务来执行某些操作的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)
}
}
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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆