jenglert jenglert - 1 month ago 16
Java Question

Mocking interface clone method

Mocking a

clone()
method on an interface appears to no longer be working with Mockito 2.1.0. The below code works fine with Mockito 1.10.19 but throws an
IllegalAccessError
with Mockito 2.1.0:

public interface CloneableInterface extends Cloneable {
CloneableInterface clone();
}

public class CloneableInterfaceTest {

@Test
public void test() {
CloneableInterface i = Mockito.mock(CloneableInterface.class);
Mockito.when(i.clone()).thenReturn(i); // Throws IllegalAccessError
}
}


Result of running above test:

java.lang.IllegalAccessError: CloneableInterface$MockitoMock$833899610.clone()LCloneableInterface;


I checked the mockito bug list and googled a bit but found nothing. Wanted to check SO community first before filing a bug report with the mockito team.

Environment: JDK 1.8.0_102, JUnit 4.11, Mockito 2.1.0, Gradle 3.0, Windows 10

EDIT: Filed a bug with the mockito team here

Answer

This is a bug in Mockito.

Since Object::clone is protected and since Java favors subclass inheritance over interface inheritance, the automatically generated subclass overrides clone as a protected method, rather than a public method. Of course, Mockito should render all overridden methods as public but currently Mockito is not doing this. This is however trivial to fix. Expect this to be resolved in a future release.