EasyMock 捕获抛出 NullPointerException

EasyMock capture throws NullPointerException

我突然发现一个问题,我需要捕获这个接口的参数:

public interface MyInterface {

    void doSomething(long id);
}
@Mock
private MyInterface myInterface;

...

Capture<Long> capturedId = Capture.newInstance();
myInterface.doSomething(capture(capturedId));

测试很早就失败了:

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.runReflectiveCall(FrameworkMethod.java:47)
  at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)

我检查了三次 null 没有通过,这是怎么回事?

问题是 EasyMock#capture(Capture<T>) 方法的实现总是 returns null:

public static <T> T capture(final Capture<T> captured) {
    reportMatcher(new Captures<T>(captured));
    return null;
}

如果模拟方法接受对象类型 Long 作为参数,这将不是问题:

void doSomething(long id);

...但是,存在 long 原始类型,并且 EasyMock#capture(Capture<T>) 方法的 return 值 (null) 的拆箱尝试失败 NullPointerException.

修复很简单:为此,引入了适合原始类型的方法变体,例如 EasyMock#captureLong(Capture<Long>):

myInterface.doSomething(captureLong(capturedId));