0

I have the following class that extends an Abstract class

public class MyConverter extends AbstractConverter<A, B> {
  @Override
  public B convert(A source) {
    // implementation here
  }
}

AbstractConverter is from org.modelmapper, it's declaration is the following:

public abstract class AbstractConverter<S, D> implements Converter<S, D> { 
   ... 
}

Now, from a Groovy file that uses Spock I want to mock my class:

class ATestOverThere extends Specification {
  def myConverter = Mock(MyConverter) // THIS THROWS THE EXCEPTION

  ...
 }

But I'm getting the folling exception when initializing the mock.

java.lang.IllegalArgumentException
at net.sf.cglib.proxy.BridgeMethodResolver.resolveAll(BridgeMethodResolver.java:61)
at net.sf.cglib.proxy.Enhancer.emitMethods(Enhancer.java:911)
at net.sf.cglib.proxy.Enhancer.generateClass(Enhancer.java:498)
at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at net.sf.cglib.proxy.Enhancer.createClass(Enhancer.java:317)
at org.spockframework.mock.runtime.ProxyBasedMockFactory$CglibMockFactory.createMock(ProxyBasedMockFactory.java:154)
at org.spockframework.mock.runtime.ProxyBasedMockFactory.create(ProxyBasedMockFactory.java:68)
at org.spockframework.mock.runtime.JavaMockFactory.createInternal(JavaMockFactory.java:59)
at org.spockframework.mock.runtime.JavaMockFactory.create(JavaMockFactory.java:40)
at org.spockframework.mock.runtime.CompositeMockFactory.create(CompositeMockFactory.java:44)
at org.spockframework.lang.SpecInternals.createMock(SpecInternals.java:51)
at org.spockframework.lang.SpecInternals.createMockImpl(SpecInternals.java:296)
at org.spockframework.lang.SpecInternals.createMockImpl(SpecInternals.java:286)
at org.spockframework.lang.SpecInternals.MockImpl(SpecInternals.java:105)
at com.tuenti.services.argentina.business.products.sva.SvaManagerSpec.$spock_initializeFields(SvaManagerSpec.groovy:14)

Seems that I'm not able to mock a class that extends an abstract class with Spock, can I?

Manu Artero
  • 9,238
  • 6
  • 58
  • 73
  • 2
    Possible duplicate of [Runtime Exception Mocking groovy.sql in Spock](https://stackoverflow.com/questions/24148802/runtime-exception-mocking-groovy-sql-in-spock) – Michael Easter May 21 '18 at 11:13
  • I believe this is a duplicate question. For more info, see this post (I was able to get your example to work by adding the objenesis and byte-buddy libs) - https://semaphoreci.com/community/tutorials/stubbing-and-mocking-in-java-with-the-spock-testing-framework – Michael Easter May 21 '18 at 11:15
  • While it is true that _Objenesis_ is needed here in addition to _CGLIB_, _ByteBuddy_ is not necessary. – kriegaex May 26 '18 at 05:06

1 Answers1

2

With Objenesis in addition to CGLIB on the classpath, as Michael Easter correctly said, your example works. No need to use ByteBuddy, though.

See also the Spock manual.

<!-- (...) -->
<dependency>
  <groupId>cglib</groupId>
  <artifactId>cglib-nodep</artifactId>
  <version>3.2.5</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.objenesis</groupId>
  <artifactId>objenesis</artifactId>
  <version>2.5.1</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.modelmapper</groupId>
  <artifactId>modelmapper</artifactId>
  <version>2.0.0</version>
  <scope>compile</scope>
</dependency>
<!-- (...) -->
package de.scrum_master.stackoverflow;

import org.modelmapper.AbstractConverter;

public class MyConverter extends AbstractConverter<Integer, String> {
  @Override
  protected String convert(Integer source) {
    return source.toString();
  }
}
package de.scrum_master.stackoverflow

import spock.lang.Specification

class MyConverterTest extends Specification {
  def "test"() {
    given:
    def myConverter = Mock(MyConverter) {
      convert(_) >>> ["one", "two"] >> { callRealMethod() }
    }

    expect:
    myConverter.convert(11) == "one"
    myConverter.convert(22) == "two"
    myConverter.convert(11) == "11"
    myConverter.convert(22) == "22"
  }
}
kriegaex
  • 63,017
  • 15
  • 111
  • 202