Java Mockito在Android上构建>=5.0,但不是安卓4.4

Java Mockito在Android上构建>=5.0,但不是安卓4.4,java,android,mockito,android-5.0-lollipop,android-4.4-kitkat,Java,Android,Mockito,Android 5.0 Lollipop,Android 4.4 Kitkat,因此,我有一个测试套件,可以在Android 4.4.4上正常运行。然而,当我测试安卓5.0.0或安卓6.0.0时,Mockito开始给我带来一系列不同的问题。我正在使用Mockitov1.9.5,但尝试了1.10.19和2.0.49-beta,但出现了相同的错误。例如,我的设置代码中包含以下内容: import static org.mockito.Mockito.*; ... MyClass myClass = mock(myClass.class); when(myClass.myMe

因此,我有一个测试套件,可以在Android 4.4.4上正常运行。然而,当我测试安卓5.0.0或安卓6.0.0时,Mockito开始给我带来一系列不同的问题。我正在使用Mockito
v1.9.5
,但尝试了
1.10.19
2.0.49-beta
,但出现了相同的错误。例如,我的设置代码中包含以下内容:

import static org.mockito.Mockito.*;

...

MyClass myClass = mock(myClass.class);
when(myClass.myMethod()).thenReturn(5L);
类方法看起来像

class MyClass {
    private long myPrivateVariable;

    synchronized long myMethod() {
        return myPrivateVariable
    }
}
在安卓4.4.4上,这很好,但在安卓5.0.0上,我遇到以下错误:

org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);

Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
2. inside when() you don't call method on mock but on some other object.
3. the parent of the mocked class is not public.
It is a limitation of the mock engine.
另一个例子是在一个例子中,我模拟一个类并调用一个方法

AnotherClass anotherClass = mock(AnotherClass.class)
但是,当调用该类的方法时,它会引发
NullPointerException
,因为该类上的私有属性未设置,而公共方法需要它

class AnotherClass {
    private PrivateAttribute privateAttribute;

    synchronized Map<String, Object> getAttribute(SomeClass instance) {
        return privateAttribute.getSomething(instance);
    }
}
另一个类{
私有私有属性私有属性;
同步映射getAttribute(SomeClass实例){
返回privateAttribute.getSomething(实例);
}
}

这在Android 5.0.0和Android 6.0.0(而不是Android 4.4.4)中引发了一个
NullPointerException
,这看起来像是当一个方法成为以前没有的
final
时可能发生的事情。您能否确认
MyClass
AnotherClass
被视为mock,而不是spies,并且您的类(或您在上述代码中省略的任何父类)都没有对相关方法或类本身进行最终修改,MyClass实例被传递给构造函数,在那里它成为最终实例。但是,这会在代码中的这一点之后发生。第二个似乎与最终属性没有任何关系。他们也是嘲弄者,而不是间谍。为什么最终会突破5.0.0而不是4.4.4?Mockito的一个危险是它是在代理子类上实现的,有效地覆盖了所有方法。如果您的类将任何Android基础设施子类化,并且如果父类中的方法成为final,那么Java将不会在适当的时间调用Mockito的override方法。在其他情况下,这会导致类似于您的异常,这就是我提出此问题的原因。但是请注意,final类与final字段非常不同,所以我所说的“final class”只是指带有
final
修饰符的类。
final
字段不相关;它的行为类似于一个
常量
。这看起来像是当一个方法成为
final
之前所没有的那种情况。您能否确认
MyClass
AnotherClass
被视为mock,而不是spies,并且您的类(或您在上述代码中省略的任何父类)都没有对相关方法或类本身进行最终修改,MyClass实例被传递给构造函数,在那里它成为最终实例。但是,这会在代码中的这一点之后发生。第二个似乎与最终属性没有任何关系。他们也是嘲弄者,而不是间谍。为什么最终会突破5.0.0而不是4.4.4?Mockito的一个危险是它是在代理子类上实现的,有效地覆盖了所有方法。如果您的类将任何Android基础设施子类化,并且如果父类中的方法成为final,那么Java将不会在适当的时间调用Mockito的override方法。在其他情况下,这会导致类似于您的异常,这就是我提出此问题的原因。但是请注意,final类与final字段非常不同,所以我所说的“final class”只是指带有
final
修饰符的类。
final
字段不相关;它的行为类似于
常量