经过一周的学du习da
我终于明白,原来我们在安卓上的单测靠robolectric是不行的
classLoader的不同
首先明确一个概念
@Runwith 这个注解代表了本次单测运行的环境
其实也代表了本次运行使用的classLoader是什么
这个很重要,因为经常会出现稀奇古怪的NPE问题,都是这个classLoader出问题
关于这个类加载器的问题,可先阅读
https://www.jianshu.com/p/0848a47d37ab
robolectric的类加载器
叫Android$SandBoxClassLoader
PowerMockito的类加载器叫
MockAssistJavaClassLoader
(报错信息里会有这样的说明的)
我们用PowerMockito mock某个方法,可是该方法内又调用了某个Android 类的时候,就可能出现
java.lang.LinkageError: loader constraint violation: when resolving method "方法签名..类名A;" the class loader (instance of org/powermock/core/classloader/javassist/JavassistMockClassLoader) of the current class, 类名B, and the class loader (instance of org/robolectric/internal/AndroidSandbox$SdkSandboxClassLoader) for the method's defining class, 类名A, have different Class objects for the type 类名B used in the signature
解决方案就是对类名A加到 @Ignore的注解参数里。
mock跟spy的差别
一开始,我在使用这两个api的时候,我总是在纠结 需要被mock的参数的内部调用,我总是在用spy,还特别规整的去调用某个类的构造函数。
后来才发现,很多情况下,直接用mock就行了。
我干嘛要关心内部调用呢?
mock出来的对象仅仅就是为了不要NPE,这个对象内部也不会真的去实现方法
mock静态方法
Mockito不能mock静态方法
只能用PowerMockito
记得加上PowerMockitoRule,这个很重要。
mock私有方法也是一样
网友评论