Java 用泛型方法模拟

Java 用泛型方法模拟,java,android,generics,mockito,Java,Android,Generics,Mockito,我试图用mockito在我的类上模拟一个泛型方法,但是当测试代码运行时,我总是得到一个NullPointerException 这是我想模仿的班级 public abstract class MyClass{ public abstract <T> T find(T t); } 最后,我要测试的类是BroadcastReceiver类的扩展,这是我要测试的代码 public class MyReceiver extendes BroadcastReceiver{

我试图用mockito在我的类上模拟一个泛型方法,但是当测试代码运行时,我总是得到一个NullPointerException

这是我想模仿的班级

public abstract class MyClass{
      public abstract <T> T find(T t);
}
最后,我要测试的类是BroadcastReceiver类的扩展,这是我要测试的代码

public class MyReceiver extendes BroadcastReceiver{
       public onReceive(Context context , Intent intent){
             ...
             ...
             myClass.find(this);
       }
}
问题在于对班级的嘲弄。该类实际上会被模拟(它不是null),但是当调用泛型方法时,我会得到null

有什么想法吗


谢谢你

这里有一个解决方案应该适合你,即使你有部分模拟(即,对于某些方法,你希望调用真实的方法,而有时你需要模拟):

公共类AbstractMethodMocker实现了Answer{
@凌驾
公共对象应答(InvocationMock调用)抛出Throwable
{
回答;
if(isAbstract(invocation.getMethod().getModifiers())
回答=返回默认值;
其他的
回答=调用实际方法;
返回应答。应答(调用);
}
}
@试验
public void testOnReceive(){
MyClass clazz=mock(MyClass.class,新的AbstractMethodMocker());
当(clazz.find)(any(BroadcastReceiver.class)),然后返回(BroadcastReceiver);
onReceive(上下文、意图);
}

它讨论了使用Mockito框架处理抽象类(及其方法)的策略。

我的解决方案与Tim建议的类似,但使用了不同类型的Answer对象。 虽然我不完全明白为什么,但对我起作用的是以下几点

MyClass myClass = Mockito.mock(MyClass.class , Mockito.RETURNS_DEEP_STUBS);

在此之后,我不需要指定任何有关何时调用该方法的信息。

能否将相关堆栈跟踪粘贴到pastebin中?我看不到myClass.find的结果(此)正在onReceive方法中使用,因此我无法理解NPE是否由于find方法返回null而引发。堆栈跟踪中没有太多信息。当调用myClass.find方法时,NPE测试失败。这是堆栈的顶部。因此,基本上你是说同一模拟类的非泛型方法ods工作正常,而泛型ods工作正常?您是否在同一个测试用例中测试了非泛型方法?如果您可以指定每个代码段的完整代码,这将非常有帮助。因为不清楚测试的是哪个类,以及模拟是如何注入目标类的。我刚刚用测试设置测试了一个类似的场景,它工作正常d对我来说。可能是您在测试的类上缺少@InjectMocks注释,或者忘记在测试设置方法中调用MockitoAnnotations.initMocks(this)。您好,Tim。不幸的是,您的解决方案对我不起作用。当测试失败时,我仍然会收到相同的错误。不知何故,该对象不是为特定的泛型参数创建的。
public class AbstractMethodMocker implements Answer<Object> {
    @Override
    public Object answer(InvocationOnMock invocation) throws Throwable
    {
        Answer<Object> answer;
        if (isAbstract(invocation.getMethod().getModifiers()))
            answer = RETURNS_DEFAULTS;
        else
            answer = CALLS_REAL_METHODS;
        return answer.answer(invocation);
    }
}

@Test
public void testOnReceive() {
    MyClass clazz = mock(MyClass.class, new AbstractMethodMocker());
    when(clazz.find(any(BroadcastReceiver.class)).thenReturn(broadcastReceiver);
    myReceiver.onReceive(context, intent);
}
MyClass myClass = Mockito.mock(MyClass.class , Mockito.RETURNS_DEEP_STUBS);