Issue
I suddenly stumbled upon an issue that I need to capture a parameter of this interface called:
public interface MyInterface {
void doSomething(long id);
}
@Mock
private MyInterface myInterface;
...
Capture<Long> capturedId = Capture.newInstance();
myInterface.doSomething(capture(capturedId));
The test failed quite early:
java.lang.NullPointerException at com.mycompany.MyInterfaceTest.doSomethingTest(MyInterfaceTest.java:81) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
I triple-checked that no way a null
is passed, what is going on?
Solution
The issue is the implementation of the EasyMock#capture(Capture<T>)
method that always returns null
:
public static <T> T capture(final Capture<T> captured) {
reportMatcher(new Captures<T>(captured));
return null;
}
This would not be a problem if the mocked method would accept an object type Long
as a parameter:
void doSomething(long id);
... however, the long
primitive type is present and the attempt of unboxing the return value (null
) of the EasyMock#capture(Capture<T>)
method fails on NullPointerException
.
The fix is simple: For this reason, there were introduced method variations suitable for primitive types, such as EasyMock#captureLong(Capture<Long>)
:
myInterface.doSomething(captureLong(capturedId));
Answered By - Nikolas Charalambidis
Answer Checked By - Willingham (JavaFixing Volunteer)