PowerMockito的简单的介绍

  1. 我们的依赖的配置
<properties>
    <powermock.version>1.5.6</powermock.version>
</properties>
<dependencies>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>${powermock.version}</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito</artifactId>
    <version>${powermock.version}</version>
    <scope>test</scope>
</dependency>
</dependencies>
  1. 使用的场景

    在现实的软件开发过程中,我们经常需要协同其他同事一起来完成某个模块的功能开发,或者需要第三方资源,比如您需要一个短信网关,您需要一个数据库,您需要一个消息中间件,当您进行测试依赖于这些资源的代码时候,不可能在每次都具备相应的环境,这将是一个很不现实的问题,如果当您依赖于其他模块而无法进行单元测试的时候,此时该模块的质量风险就有两个,第一是您所负责的代码,第二是您所依赖的代码,您所依赖您没有办法在很快的时间协调到资源, 那么您所负责的代码由于不具备单元测试环境没有办法进行测试,很可能存在极大的风险,因此如何测试您的代码,让他的质量达到百分之百的可用, 这就是 Mock 存在的必要。我们如何在没有数据库的时候能够测试我们的 Service,进行支付的测试等等,这才是 Mock 要解决的问题PowerMock(PowerMock 也是一种 Mock,但是他主要是解决其他 Mock 不能解决的问题)

在做单元测试的时候,我们会发现我们要测试的方法会引用很多外部依赖的对象,比如:(发送邮件,网络通讯,远程服务, 文件系统等等)。 而我们没法控制这些外部依赖的对象,为了解决这个问题,我们就需要用到Mock工具来模拟这些外部依赖的对象,来完成单元测试。

今天我在测试的时候,需要一个HttpResponse对象哦~怎么办呢?只有模拟这个对象啦!不知道可以不~~

  1. hello word 的使用!获取所有员工的个数

    我们现在有一个 Service 类,就是 EmployeeService,其中有一个方法需要获取数据库中雇员的数量,Service 代码如下所示:

import com.wangwenjun.powermock.helloworld.dao.EmployeeDao;
public class EmployeeService {
private EmployeeDao employeeDao;
    public EmployeeService(EmployeeDao employeeDao)
    {
        this.employeeDao = employeeDao;
    }
/**
* 获取所有员工的数量.
* @return
*/
    public int getTotalEmployee()
    {
        return employeeDao.getTotal();
    }
}

可以看到, 创建 Service 的时候需要传递一个 EmployeeDao 这个类, 也就是说 Service依赖于 Persistence,如果想要测试 Service 就需要完全看 Persistence 的脸色,我们再来看看 Persistence 代码,如下所示

public class EmployeeDao {
    public int getTotal()
    {
        throw new UnsupportedOperationException();
    }
}

哇!你死定了,你肯定调用不了 Dao,无法正常完成 Service 的测试,我为什么要在Persistence的方法抛出UnsupportedOperationException呢?目的就是告诉大家该方法可能由于某种原因(没有完成,或者资源不存在等)无法为 Service 服务,难道你不需要测试 EmployeeService 么?肯定要测试,那么我们就硬着头皮来写测试用例吧

import static org.junit.Assert.assertEquals;
import org.junit.Test;
import com.wangwenjun.powermock.helloworld.dao.EmployeeDao;
public class EmployeeServiceTest {
    @Test
    public void testGetTotalEmployee() {
        final EmployeeDao employeeDao = new EmployeeDao();
        final EmployeeService service = new EmployeeService(employeeDao);
        int total = service.getTotalEmployee();
        assertEquals(10, total);
    }
}

比较的遗憾,这个肯定的会失败的哦~不会成功的,我们的Dao层的数据都还没有实现怎么可能会有好的数据返回呢?

所以啊,这个时候我们就模拟啊~,当我们的service层调用代码的时候,我们就可以使用啦!employeeDao.getTotal();

我们要去模拟这个方法的返回值,必须的去请求我们的返回的数据,这个时候就是模拟啦!

请大家忘记此时此刻我抛出来的异常,幻想成此时此刻数据库连接不上,问题现在很明显,数据库链接不通,我们无法测试 Service,难道真的就无计可施了么?好吧,有请我们的主角 PowerMock 闪亮登场,请看下面的测试用例

import org.junit.Test;
import org.powermock.api.mockito.PowerMockito;
import com.wangwenjun.powermock.helloworld.dao.EmployeeDao;
public class EmployeeServiceTest {
@Test
public void testGetTotalEmployeeWithMock() {
    EmployeeDao employeeDao = PowerMockito.mock(EmployeeDao.class);
    PowerMockito.when(employeeDao.getTotal()).thenReturn(10);//当我们调用这个方法的时候的返回值是10!这样就好了涩,我们不是就模拟出来啦数据啦~
    EmployeeService service = new EmployeeService(employeeDao);
    int total = service.getTotalEmployee();
    assertEquals(10, total);
}
}

当你再次运行时你会发现此时此刻运行通过, 编写一下上述的代码我们先来有个简单的认识,所谓 Mock 就是创建一个假的,Mock 那个对象就会创建一个假的该对象,此时该对象是一单纯的白纸,需要你对其进行涂鸦,第二句话 when…then 语法就是您的涂鸦, 您期望调用某个方法的时候返回某个您指定的值。完全让 EmployeeDao 根据你的意愿来运行,所以想怎样测试 EmployeeService 就怎样测试。

  • 创建员工 返回值为void的测试!

    我们再来增加另外一个需求,就是创建一个 Employee,这就意味着我们需要分别在Service 和 Dao 中增加相应的两个接口

Service 中的 CreateEmployee 方法
public void createEmployee(Employee employee)
{
    employeeDao.addEmployee(employee);
}

再来看看 Dao 中的方法 addEmployee  没有返回值哦~由于某些原因呢,我们就是没得返回值啦~
public void addEmployee(Employee employee)
{
    throw new UnsupportedOperationException();
}

因为此时“数据库资源不存在” ,相信大家一定很清楚这一点,但是这不是本小节中所要讲述的重点,重点在于 addEmployee 方法是一个 void类型的,也就是我们没有办法断言想要的结果是否一致,而 mock 厚的 addEmployee 方法事实上是什么都不会做的,此时我们该如何进行测试呢? 比如log记录日志…里面含有httpsession对象,我们也是可以不需要打印日志的,直接不管他啦!但是测试的时候我们不能把他直接注释掉啊!忘记了怎么办呢?这样的方式很不对!以前我测试的时候也是这么直接的处理的,实习呢之后的今天,看到了这个非常的好奇哦,还不错,学到了好东西!测试非常的有必要,比编写代码更重要。反正我写测试比编写代码的时间多!

简单思考一下我们其实只是想要知道 addEmployee 方法是否被调用过即可, 当然我们可以假设他 add 成功或者失败,这就根据您的 test case 来设定了,好了,有了这个概念之后我们来看看如何测试 void 方法,其实就是 mock 中一个很重要的概念 Verifying

@Test
public void testCreateEmployee() {
    EmployeeDao employeeDao = PowerMockito.mock(EmployeeDao.class);
    Employee employee = new Employee();
    PowerMockito.doNothing().when(employeeDao).addEmployee(employee);//当我们使用这个方法的时候我们什么都不做哦,仅仅测试哈,是否调用了这个方法就好了!
    EmployeeService service = new EmployeeService(employeeDao);
    service.createEmployee(employee);
    // verify the method invocation.
    Mockito.verify(employeeDao).addEmployee(employee);
}

然后用 junit 运行肯定能够通过, 其中 Mockito.verify 主要用来校验被 mock 出来的对象中的某个方法是否被调用,我们的 PowerMock helloworld 也到此结束了。

时间: 2024-08-24 23:55:33

PowerMockito的简单的介绍的相关文章

简单的介绍下WPF中的MVVM框架

最近在研究学习Swift,苹果希望它迅速取代复杂的Objective-C开发,引发了一大堆热潮去学它,放眼望去各个培训机构都已打着Swift开发0基础快速上手的招牌了.不过我觉得,等同于无C++基础上手学习C#一样,即使将来OC被淘汰,那也是N年之后的事情,如果真的要做IOS开发,趁现在Swift才刚开始,花那么几个月去了解一下OC绝对是一件有帮助的事情. 扯远了,我前几天刚接触到一个叫做mvvm的框架,发现很有意思,带着学习的态度来写点东西,不足之处一起研究.还有一个很重要的原因,我发现不少同

vue学习笔记——简单的介绍以及安装(一)

学习编程需要的是 API+不断地练习^_^ Vue官网:https://cn.vuejs.org/ 菜鸟教程:http://www.runoob.com/vue2/vue-tutorial.html 1.简单的介绍 Vue.js(读音 /vju?/, 类似于 view) 是一套构建用户界面的渐进式框架. Vue 只关注视图层, 采用自底向上增量开发的设计. Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件. Vue 学习起来非常简单,本教程基于 Vue 2.1.8 版

【转】简单了介绍js中的一些概念(词法结构) 和 数据类型(部分)。

1 , javascript字符集: javascript采用的是Unicode字符集编码. 为什么要采用这个编码呢? 原因很简单,16位的Unicode编码可以表示地球人的任何书面语言.这是语言 国际化的一个重要特征.(大家也许见过用中文写脚本,比如:function 我的函数() {} ); Javascript中每个字符都是用2个字节表示的.(因为是16位编码) 2 ,大小写敏感: js是一种区分大小写的语言. 注意下:以前我也犯过的错误. HTML是不区分大小写的.经常看见有人这么写, 

A*算法最简单的介绍

A*搜寻算法,俗称A星算法,作为启发式搜索算法中的一种,这是一种在图形平面上,有多个节点的路径,求出最低通过成本的算法.常用于游戏中的NPC的移动计算,或线上游戏的BOT的移动计算上.该算法像Dijkstra算法一样,可以找到一条最短路径:也像BFS一样,进行启发式的搜索. A*算法最为核心的部分,就在于它的一个估值函数的设计上:        f(n)=g(n)+h(n) 其中f(n)是每个可能试探点的估值,它有两部分组成:    一部分,为g(n),它表示从起始搜索点到当前点的代价(通常用某

Python 模块简单的介绍

Python模块的学习: 1.os模块: 下面只对os模块中几个比较常用的方法做一些简单的示例: os.system():这个方法在shell中体现的比较多,在dos命令行中也可以执行,下面就以在dos命令行中为例,说下system方法的作用(通过这个示例,大家对system方法的实用就一目了然了): 1 >>> import os 2 >>> print(os.system('ls')) 3 'ls' 不是内部或外部命令,也不是可运行的程序 4 或批处理文件. 5 1

Mybatis缓存(1)--------系统缓存及简单配置介绍

前言 Mybatis的缓存主要有两种: 系统缓存,也就是我们一级缓存与二级缓存: 自定义的缓存,比如Redis.Enhance等,需要额外的单独配置与实现,具体日后主要学习介绍. 在这里主要记录系统缓存的一些简单概念, 并没有涉及原理.其中会涉及Mybatis的相关配置以及生命周期等. 主要参考资料:<深入浅出Mybatis基础原理与实战>,http://www.mybatis.org/mybatis-3/zh/index.html 1.Mybatis简单配置介绍 本文介绍的是基于XML的配置

MKV怎么转AVI格式?转换的简单方法介绍

MKV怎么转AVI格式?有很多时候都需要将视频文件进行不同程度的转换,那么下面小编就给大家简单的介绍一下将MKV转AVI格式的方法,希望可以帮助到大家. 步骤一:我们可以直接进入到迅捷PDF在线转换器网站中,通过在浏览器上的搜索然后进入到在线中进行:步骤二:进入到首页中,找到音视频转换中的MKV转AVI格式,然后点击进入即可:步骤三:进入之后进行视频文件的选择,将mkw格式的视频点击选择到界面中,然后点击视频文件进行选择,将视频文件选择到界面中:步骤四:选择好之后就可以进行视频文件转换,点击开始

EVE-NG简单入门介绍

此篇文章简单的介绍下模拟器EVE-NG的使用,具体包括Dynamips设备导入与运行,IOL设备的导入与运行,QEMU设备的导入与运行,客户端软件的安装,物理网络与虚拟网络的结合等. 一.导入镜像 Dynamips是由法国人Chris Fillot于2005年发布的用于模拟Cisco设备的模拟器,它可以运行标准的IOS镜像,虽然此模拟器比较陈旧,但仍然有很多网工愿意使用.EVE-NG支持Cisco IOS 1710.3725与7206,这些镜像可从思科官网或互联网上下载到.推荐使用WinSCP向

ios开发入门篇(二):Objective-C的简单语法介绍

一:面向对象的思想 objective-c与C语言的编程思想不同,C语言是面向过程的编程,而objective-c则是面向对象的编程,所谓面向对象,我个人的理解,就是抽象.将具有一定共同点的实物抽象成一个个类,对其进行封装,继承,对实物本身进行操作. 二:Objective-C的历史 objective-c是以SmallTalk为基础,建立在C语言之上,并兼容c与c++的一门编程语言.20世纪80年代早期由 Brad J.Cox设计,2007年苹果公司发布了objective-c 2.0,并在i