Mockito/PowerMockito踩坑记录

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mockito/PowerMockito踩坑记录相关的知识,希望对你有一定的参考价值。

参考技术A 经过一周的学du习da
我终于明白,原来我们在安卓上的单测靠robolectric是不行的

首先明确一个概念
@Runwith 这个注解代表了本次单测运行的环境
其实也代表了本次运行使用的classLoader是什么
这个很重要,因为经常会出现稀奇古怪的NPE问题,都是这个classLoader出问题

关于这个类加载器的问题,可先阅读
https://www.jianshu.com/p/0848a47d37ab

robolectric的类加载器
android$SandBoxClassLoader

PowerMockito的类加载器叫
MockAssistJavaClassLoader

(报错信息里会有这样的说明的)

我们用PowerMockito mock某个方法,可是该方法内又调用了某个Android 类的时候,就可能出现

解决方案就是对类名A加到 @Ignore的注解参数里。

一开始,我在使用这两个api的时候,我总是在纠结 需要被mock的参数的内部调用,我总是在用spy,还特别规整的去调用某个类的构造函数。
后来才发现,很多情况下,直接用mock就行了。
我干嘛要关心内部调用呢?
mock出来的对象仅仅就是为了不要NPE,这个对象内部也不会真的去实现方法

Mockito不能mock静态方法
只能用PowerMockito
记得加上PowerMockitoRule,这个很重要。

mock私有方法也是一样

使用PowerMockito 对静态类进行mock

Mock的中文的意思就是模拟,Mockito是mock的扩展,但是Mockito并不支持对静态类的mock,所以我们引入PowerMockito实现对静态类的mock.

首先pom添加PowerMockito 的 jar包引用,注意相应的版本号。否则会出现jar包冲突异常。

            <dependency>
			<groupId>org.mockito</groupId>
			<artifactId>mockito-all</artifactId>
			<version>1.10.8</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.powermock</groupId>
			<artifactId>powermock-api-mockito</artifactId>
			<version>1.6.1</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.powermock</groupId>
			<artifactId>powermock-module-junit4</artifactId>
			<version>1.6.1</version>
			<scope>test</scope>
		</dependency>
                   dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
                        <version>4.12</version>
			<scope>test</scope>
		</dependency>

  如例我们需要对LogUtil.class 的 静态方法进行mock,类格式如下,该类的两个方法均为静态方法。

public class LogUtil {

        public static BaseAuditLog getLogBean(String operContent){
		return null;		
	}
	
	 public static void  saveLog(String context){
		
	 }

 使用PowerMockito 测试类如下 :

@RunWith(PowerMockRunner.class)  //1.
@PrepareForTest({LogUtil.class}) //2.
public class AddressBookServiceTest_mock {


    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }
   @Test
    public void test_staticMethod_PowerMock()  { 
        //绕过静态类
        PowerMockito.mockStatic(LogUtil.class);//3.绕过静态类
        when(LogUtil.getLogBean(json)).thenReturn(new SensitiveInfoOperationLog());//4.预设静态类返回值
String response = addressBookServiceImpl.queryAddressBookFuzzy(json); } }

以上便可以实现的静态类的mock.

因为要实现单元测试,还需要实现对类成员变量进行mock.

有两种主要方法

1.通过继承方式实现

2.通过反射的方式实现

具体示例出自链接   http://blog.csdn.net/fenglibing/article/details/16842655

具体示例如下:

public     class     Address{
          boolean querySwitch= false  
}

public     class     Address_test{
        private Address    address;
        
        public void test_Address(){
        //通过反射改变类成员变量值
        boolean querySwitch=false;
        Field  field=address.getClass().getDeclaredField("querySwitch");
        field.setAccessible(true);
        field.set(address,querySwitch);
    }
  
}    

 

 

  

 

以上是关于Mockito/PowerMockito踩坑记录的主要内容,如果未能解决你的问题,请参考以下文章

使用PowerMockito和Mockito进行模拟测试,包括静态方法测试,私有方法测试等

使用PowerMockito 对静态类进行mock

PowerMockRule踩坑

powermock

Mockito的参数匹配

Mockito和PowerMock用法