简体   繁体   English

带参数的Groovy模拟Java类

[英]Groovy mock Java class with parameters

I'm trying to use groovy's MockFor and proxyDelegateInstance to mock a java class with constructor parameters, but I can't seem to get it right. 我正在尝试使用groovy的MockFor和proxyDelegateInstance来模拟带有构造函数参数的java类,但我似乎无法正确使用它。 My Java class looks like: 我的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)
    }

}

Can I actually do this in groovy? 我能在groovy中实际做到这一点吗? And if so, how can I do it? 如果是这样,我该怎么办呢?

thanks, Jeff 谢谢,杰夫

The problem was that the class being mocked was a class and not an interface. 问题是被模拟的类是一个类而不是接口。 In order to use the proxyDelegateInstance method, the an interface type needs to be used (or a groovy class). 为了使用proxyDelegateInstance方法,需要使用接口类型(或groovy类)。 The proxy class is not actually of the MyJavaClass type but is a proxy and groovy's duck typing can handle that while Java cannot. 代理类实际上不是MyJavaClass类型,但它是一个代理,并且groovy的duck typing可以处理,而Java则不能。

I can't tell you why your code above is not working, but there are several ways in Groovy to mock Java classes without using MockFor . 我不能告诉你为什么上面的代码不起作用,但是Groovy有几种方法可以在不使用MockFor情况下模拟Java类。 For example, if you want to intercept all calls to the object, you can implement invokeMethod on the classes' metaClass, eg 例如,如果要拦截对该对象的所有调用,可以在类的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
}

Alternatively, if you simply want to provide an object that supports the method signatures of SomeJavaClass , you could use either a Map or an Expando with properties where: 或者,如果您只想提供支持SomeJavaClass方法签名的SomeJavaClass ,则可以使用MapExpando ,其属性包括:

  • property names match method names 属性名称匹配方法名称
  • proprerty values are closures that accept the same parameters as methods proprerty值是接受与方法相同的参数的闭包

If you can provide a bit more information about how the mock object is used, perhaps I can provide some more specific suggestions. 如果您可以提供有关如何使用模拟对象的更多信息,也许我可以提供一些更具体的建议。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM