Jeff Storey
Jeff Storey

Reputation: 57222

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. My Java class looks like:

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? And if so, how can I do it?

thanks, Jeff

Upvotes: 4

Views: 5281

Answers (2)

Dónal
Dónal

Reputation: 187397

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. For example, if you want to intercept all calls to the object, you can implement invokeMethod on the classes' metaClass, e.g.

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:

  • property names match method names
  • proprerty values are closures that accept the same parameters as methods

If you can provide a bit more information about how the mock object is used, perhaps I can provide some more specific suggestions.

Upvotes: 4

Jeff Storey
Jeff Storey

Reputation: 57222

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). 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.

Upvotes: 5

Related Questions