单元测试不好搞阿,虽然从TDD角度出发,可测性强的代码很大程度上就代表着好的设计,但是有些情况也是没办法的,比如单例模式,比如Static方法,比如Final类,传统的Mock技术是没办法解决这些问题的,而如果单纯为了测性去修改代码,这会大大破坏代码的整体设计,所以开发不愿意搞单元测试,而测试人员更拿这不可测的代码束手无策。

好在,在Java领域,有了PowerMock

PowerMock简介

PowerMock使用自定义的类加载器和字节码操作技术,从而使得我们能够Mock: Static方法,构造函数, Final的类和方法,Private的方法,即使是静态初始化也不在话下。PowerMock的强大是不言而喻的,它不需要我们对IDE有任何的修改就可以直接使用,而且对持续集成的配置也没有任何额外影响。PowerMock是对现有Mock框架的拓展,目前它仅支持EasyMock和Mockito。

PowerMock能用于Android单元测试吗?

有经验的童鞋可能已经想到了,PowerMock之所以能够这么强大是因为它使用自定义的类加载器,并且在运行时操作字节码,所以他是根植于虚拟机环境的,而Java的虚拟机跟Android的虚拟机是不一样的,那么PowerMock能在Android的Dalvik虚拟机上执行嘛?

答案是否定的,PowerMock当前并没有提供适用于Dalvik虚拟机的类加载器,所以PowerMock在Android环境中是跑不起来的(有牛叉的童鞋可以考虑帮PowerMock实现下,记得分享~)

但是,考虑到单元测试的特点,我们并不是一定要被测程序在设备上运行起来,我们需要的是对所有功能单元进行逻辑覆盖,那么基于这一点,如果Java虚拟机与Dalvik差别不大的话,我们是不是可以在Java虚拟机上进行Android项目的单元测试呢?正是基于这点出发,Google非Android项目的童鞋想到了下面的Work Around方式。

创建Android Junit单元测试工程

假设我们有一个标准的Android项目,我们该如何创建我们的测试工程呢?

1. 不同于传统的Android测试项目创建,第一步我们得创建个标准的Java工程:

2. 选择我们刚创建的Java项目,右键选择属性,然后在Java Build Path项选择Projects标签,点击Add键,把被测Android项目加进来。

3. 下载PowerMock的工具包,这里我选择是最新的PowerMock+Mockito集合,然后全部解压到本地。

4. 然后我们要把PowerMock的工具包加到我们的项目里。同样是右键项目,选择属性到Java Build Path, 然后选择Libraries标签,使用Add External JARs功能把刚解压的所有Jar包加到项目   里。

5. 接上一步我们要把Android.jar包也加到我们的项目里,不然我们的Android项目就会编译失败。这里要注意,在我们配置Android开发环境时,我们会通过Android SDK Manager下载相应的Android版本到本地,通常这个Jar包在sdk\platforms\android-{SDK version}下,我们可以选择这个Jar包来配置我们的项目,但是有个潜在的问题就是以后当我们测试的代码用到Android包里的API时,就会直接抛一个RuntimeException:Stub!异常,这是因为原生的Android Jar包里的API是没有具体实现的,只是各种类和方法的签名,而内容就是直接抛这个RuntimeException异常,并且即使我们想Mock住这些方法也是不行的,所以最好不要用这个Jar包。那解决办法就是下载Android源码,删除这些异常,然后重新编译成Jar包供使用。在Google的文章里提供了一个Android包,但是比较旧,有可能没法用。这里有个稍微新点的,但是不知道其版本号(http://www.4shar(_)ed.com/get/KWwSl5an/android.html)(把(_)去掉)。

6. 这一步尤其重要,我们得把这几个Jar包排好序,不然可能编译不通过。同样在Java Build Path里选择Order and Export,把这些Jar包按下面的顺序排部:

至此,使用PowerMock的Android Junit环境我们就配置好了,接下来就可以写单元测试了~

参考资料

PowerMock on Android (Google Solution)

Mocking Android System Objects using PowerMock

如果您看了本篇博客,觉得对您有所收获,请点击下面的 [推荐]

如果您想转载本博客,请注明出处

如果您对本文有意见或者建议,欢迎留言

单元测试不是梦,Android+PowerMock系列(1) —— 在Eclipse里搭建测试环境的更多相关文章

  1. 简单谈谈eclipse下搭建PhoneGap环境来开发Android程序 - linux86(转)

    原来在逛园子的时候一不小心发现了一个新概念“PhoneGap”简称PG,我一直都喜欢追逐新事物,自然就产生了好奇心.于是乎我就在百度上面Google了一下PhoneGap是什么东西.简单的说就是用另一 ...

  2. Android studio 搭建测试环境 创建虚拟机

    1.打开android studio2.0 ,选择AVD Manger 2.选择Create Virtual Device 3.在左侧Category中选择Phone,然后选择自己喜欢的手机型号,点击 ...

  3. java-cef系列视频第二集:搭建开发环境

    上一集我们介绍了如何从官方代码编译java-cef. 本视频介绍了如何使用eclipse搭建java-cef二次开发环境. 下一集我们将给java-cef添加flash支持. 本作品采用知识共享署名- ...

  4. 流程引擎Activiti系列:在eclipse中搭建咖啡兔的Activiti演示工程中的各种坑及其解决方法(kft-activiti-demo-no-maven)

    近期在学习activiti,打算基于现有的框架,比如activiti-explorer或者咖啡兔的示例工程 kft-activiti-demo,在此基础上添加自己的业务流程,看看是否可以走通,以及这个 ...

  5. Android配置时,点击eclipse里Window->Preferences里的android选项出错

    An error has occurred when creating this preference page. 解决方法:重起eclipse

  6. Android开发系列之搭建开发环境

    接触Android好久了,记得09年刚在中国大陆有点苗头的时候,我就知道了google有个Android,它是智能机操作系统.后来在Android出1.5版本之后,我第一时间下载了eclipse开发工 ...

  7. Android拓展系列(11)--打造Windows下便携的Android源码阅读环境

    因为EXT和NTFS格式的差异,我一直对于windows下阅读Android源码感到不满. 前几天,想把最新的android5.0的源码下下来研究一下,而平时日常使用的又是windows环境,于是专门 ...

  8. Android学习系列(37)--App调试内存泄露之Context篇(下)

    接着<Android学习系列(36)--App调试内存泄露之Context篇(上)>继续分析. 5. AsyncTask对象 我N年前去盛大面过一次试,当时面试官极力推荐我使用AsyncT ...

  9. [转]Android Studio系列教程六--Gradle多渠道打包

    转自:http://www.stormzhang.com/devtools/2015/01/15/android-studio-tutorial6/ Android Studio系列教程六--Grad ...

随机推荐

  1. hive UDAF源代码分析

    sss /** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license a ...

  2. head first-----decorate design pattern

    浅谈设计模式之------装饰者模式     首先给出装饰者模式的定义吧:              动态的将责任附加到对象上,若是要扩展功能,装饰者提供了比继承更加具有弹性的替代方案.     其中 ...

  3. dispatch_get_current_queue 废弃

    由于iOS7以后 dispatch_get_current_queue 被废弃,所以需要寻找一个替代的方案. 发现 dispatch_get_current_queue 并没有字面上那么简单. 这个函 ...

  4. PIC16F877A最小功能板 - 原理图系列

    一.顶层 主要由port转换.MCU.复位.键盘.晶振和显示等5部分电路组成. 二.模块层 1. port转换电路 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZ ...

  5. rancher 笔记 之 rancher应用中心

    rancher应用中心 rancher 的应用中心 可以 自定义,在 admin -> catlog 中 指定路劲 rancher的应用中心 就是一个git项目 指定git的路劲的时候 填写的是 ...

  6. nginx代理人server结合tomcat采用

    相信非常多人都听过nginx,这个小巧的东西慢慢地在吞食apache和IIS的份额.那到底它有什么作用呢?可能非常多人未必了解. 说到反向代理,可能非常多人都听说,但详细什么是反向代理,非常多人预计就 ...

  7. 基于HTML5的SLG游戏开发(一):搭建开发环境(2)

          游戏开发过程中经常需要处理各种事件,而HTML5游戏开发中,所有的场景和UI面板都是绘制在Canvas上面,假设需要对某一UI面板上的关闭按钮添加事件监听,采取的方法是对关闭按钮图片资源进 ...

  8. 亲测安装php

    亲测安装php1.tar zvxf php-5.3.8.tar.gz 2.cd php-5.3.83../configure \ --prefix=/usr/local/php \--with-mys ...

  9. 解决mybatis使用枚举的转换

    解决mybatis使用枚举的转换 >>>>>>>>>>>>>>>>>>>>> ...

  10. 第四篇:python 高级之面向对象初级

    python 高级之面向对象初级   python 高级之面向对象初级 本节内容 类的创建 类的构造方法 面向对象之封装 面向对象之继承 面向对象之多态 面向对象之成员 property 1.类的创建 ...