2010-02-09 41 views
4

我想使用groovy的MockFor和proxyDelegateInstance模拟一个具有构造函数参数的java类,但我似乎无法弄清楚它的正确性。我的Java类看起来像:Groovy模拟Java参数的类

class MyJavaClass { 
    private MyObject myObj 
    public MyJavaClass(MyObject myObj) { 
     this.myObj = myObj; 
    } 
} 

class MyGroovyTest { 
    @Test 
    void testMyJavaClass() { 
     def mock = new MockFor(MyJavaClass) 
     MyJavaClass mjc = new MyJavaClass() 
     def mockProxy = mock.proxyDelegateInstance([mjc] as Object[]) 
     // if I pass mockProxy to anything, I get an error that a matching 
     // constructor could not be found. I've tried variations on the args 
     // to proxyDelegateInstance (such as using mjc as a single arg rather than 
     // an array of one element) 
    } 

} 

我可以在groovy中做到这一点吗?如果是这样,我该怎么做?

感谢, 杰夫

回答

5

问题是被模拟的类是一个类而不是接口。为了使用proxyDelegateInstance方法,需要使用一个接口类型(或一个常规类)。代理类实际上并不是MyJavaClass类型,但是它是一个代理,Groovy的鸭子类型可以处理,而Java不能。

+0

您最终使用的是什么? – user944849 2016-09-28 16:43:52

4

我不能告诉你为什么你上面的代码不工作,但也有在Groovy几种方式来嘲笑Java类,而无需使用MockFor。例如,如果要拦截对该对象的所有调用,则可以在类的metaClass上实现invokeMethod,例如,

class SomeJavaClass { 
    // methods not shown 
} 

def instance = new SomeJavaClass() 

instance.metaClass.invokeMethod = {String name, args -> 
    // this will be called for all methods invoked on instance 
} 

或者,如果你只是想提供支持的SomeJavaClass方法签名的对象,你可以使用一个MapExpando与性质其中:

  • 属性名称匹配方法名
  • 特许值是接受与方法相同的参数的闭包

如果您可以提供更多有关如何使用模拟对象的信息,也许我可以提供一些更具体的建议。

+0

不,问题是如果我有另一个类,我们称之为Actor,它将MyJavaClass作为参数,我调用actor.doSomething(mockProxy)我得到一个关于没有合适的构造函数来创建MyJavaClass的错误。 – 2010-02-09 18:30:08

+0

如果Actor没有真正实例化MyJavaClass,那么您能否正常实例化MyJavaClass,并使用invokeMethod来覆盖方法实现? – 2010-02-09 19:14:46

+0

在测试结束时,我需要验证MyJavaClass,这就是为什么我将它创建为模拟的原因。 – 2010-02-09 19:26:04