Skip to content

ClassNotFoundException when stubbing array of primitive type on Android #3752

@jselbo

Description

@jselbo

Suppose:

public class Foo {
  public byte[] getData(List<String> args) { ... }
}
public class MyTest {
  @Test
  public void myTest() {
    Foo mockFoo = mock(Foo.class);
    when(mockFoo.getData(any())).thenReturn(null);
  }
}

When running as an instrumentation test on an Android API 30 emulator with latest Mockito, this results in:

java.lang.IllegalStateException: This was not supposed to happen.
	at org.mockito.internal.util.reflection.GenericMetadataSupport$GenericArrayReturnType.rawType(GenericMetadataSupport.java:565)
	at org.mockito.internal.stubbing.answers.InvocationInfo.isVoid(InvocationInfo.java:98)
	at org.mockito.internal.stubbing.answers.Returns.validateFor(Returns.java:34)
	at org.mockito.internal.stubbing.InvocationContainerImpl.addAnswer(InvocationContainerImpl.java:65)
	at org.mockito.internal.stubbing.InvocationContainerImpl.addAnswer(InvocationContainerImpl.java:56)
	at org.mockito.internal.stubbing.OngoingStubbingImpl.thenAnswer(OngoingStubbingImpl.java:32)
	at org.mockito.internal.stubbing.BaseStubbing.thenReturn(BaseStubbing.java:34)
	at com.example.MyTest.myTest.(MyTest.java:50)
	... 38 trimmed
Caused by: java.lang.ClassNotFoundException: [Lbyte;
	at java.lang.Class.classForName(Native Method)
	at java.lang.Class.forName(Class.java:454)
	at org.mockito.internal.util.reflection.GenericMetadataSupport$GenericArrayReturnType.rawType(GenericMetadataSupport.java:556)
	... 46 more
Caused by: java.lang.ClassNotFoundException: byte
	at java.lang.Class.classForName(Native Method)
	at java.lang.BootClassLoader.findClass(ClassLoader.java:1358)
	at java.lang.BootClassLoader.loadClass(ClassLoader.java:1418)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
	... 49 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available

After some investigation, it looks like Method.getGenericReturnType() is implemented differently on Android and this results in a different code path that wasn't designed to handle primitives. I'll open a PR for this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions