Home > Back-end >  Spock mock multiple interfaces
Spock mock multiple interfaces

Time:03-16

I have a Jax-WS Webservice call which is enclosed in a class which I need to test using spock. The implementation of the webservice call is done in a superclass which I can't change. I would prefer to do a redesign and get rid of the inheritance but I can't do that.

For my unit test I wan't to mock the webservice. The code which creates the port looks like this:

MyPortType client = createServiceClient(); //inherited from superclass, needs to be mocked
(BindingProvider) bp = (BindingProvider) client;

That cast to BindingProvider is always safe with JAX-WS, so that's not a problem. However I need to mock the createServiceClient() method and I need it to return a mock which implements both MyPortType and BindingProvider.

Here's what I've got so far:

MyPortType port = Mock(MyPortType) as BindingProvider
port.myMethod(_ as MyType) >> Mock(MyResponse)

But I get this exception:

java.lang.AbstractMethodError: Receiver class $Proxy541_groovyProxy does not define or inherit an implementation of the resolved method 'abstract MyResponse myMethod(MyType)' of interface MyPortType.

I suspect that I'm still defining the MyPortType Mock the wrong way, but I can't figure it out.

Has anybody tried this kind of thing before?

EDIT: Both of these return true, so it would seem, that the mock for the class works, but the mock for the method does not:

port instanceof MyPortType
port instanceof BindingProvider

CodePudding user response:

You want to use Mock(MyPortType, additionalInterfaces: [BindingProvider]), i.e. A la Carte Mocks. However, there is an open issue which prevents defining responses for the additional interfaces methods, so it will only pass instanceof checks. As a workaround you can define a test interface that extends both interfaces.

interface TestPortType extends MyPortType, BindingProvider {}
// ...
TestPortType port = Mock(TestPortType)
  • Related