Mockito是一种用于替代在测试中难以实现的成员,从而让testcase能顺利覆盖到目标代码的手段。下面例子将展示Mockito的使用。

完整代码下载:https://files.cnblogs.com/files/xiandedanteng/mockitoTest20200311.zip

首先有这么一个需要测试的类:

package mockito;

public class EmpService {
private EmpDao dao; public EmpService() {
dao=new EmpDao();
} public boolean isWeakPswd(long empId) {
// roadlock which hinder running bacause of no environment
Emp emp=dao.getById(empId); // Real code need to be tested,but unreachable because emp is null
if(emp.getPswd().equals("111111")) {
return true;
}else if(emp.getPswd().equals("123456")) {
return true;
}else if(emp.getName().equals(emp.getPswd())) {
return true;
}else {
return false;
}
}
}

其中isWeakPswd是需要测试的方法,但问题是dao不能在测试环境中就绪,因此跑不到下面的if语句。

package mockito;

public class EmpDao {
public Emp getById(long id) {
// Access auth/redis/db to get a real emp,but it is difficult to set up environment in test,so return null
return null;
}
}

EmpDao的getById方法不能就绪的原因是需要搭建完整的认证/redis/db环境,总之搞不成就是了。大家在测试某些类也会发生内部的mapper,dao不能就绪的情况,这和本例情况类似。

然后下面的测试方法就走不下去了,因为一跑isWeakPswd方法就会抛出空指针异常;

    @Test
public void normalTestWeakPswd() {
EmpService service=new EmpService(); // NullPointerException will be thrown out and case will fail
boolean actual=service.isWeakPswd(10001); Assert.assertSame(true, actual);
}

然后怎么办呢?任凭Coverrage在低位徘徊?当然不是,这个时候就该请Mock出场了。

Mock本身就是个空壳,作用是替代无法就绪的对象,达到测试其后代码的目的。下面就制作了mockDao用来替代EmpService里的empDao

    @Test
public void testWeakPswd_ByMock_01() throws Exception {
EmpDao mockDao = Mockito.mock(EmpDao.class); // 创建
Emp emp=new Emp(10001,"Andy","111111"); // 返回值
Mockito.when(mockDao.getById(10001)).thenReturn(emp);// 设置调用getById时返回固定值 // Use reflection replace dao with mockDao,利用反射用mock对象取代原有的empDao
EmpService service=new EmpService();
Field daoField = service.getClass().getDeclaredField("dao");
daoField.setAccessible(true);
daoField.set(service, mockDao); Assert.assertEquals(true, service.isWeakPswd(10001));// 这样,isWeakPswd方法就不会抛出空指针异常了
}

这样,Mock对象就当好了替补队员的角色,使得isWeakPswd的代码可以达到了。

Mockito的使用就这样简单,无非是创建,设定要模拟的函数的返回值(或异常),然后用反射方法进行顶替三部曲,下面是测试类的全部代码:

package mockitoTest;

import java.lang.reflect.Field;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.Mockito; import mockito.Emp;
import mockito.EmpDao;
import mockito.EmpService; public class EmpServiceTest {
@Rule
public ExpectedException exception = ExpectedException.none(); // No Exception thrown Allowed private EmpDao memberMockDao; @Before
public void init() throws Exception {
memberMockDao = Mockito.mock(EmpDao.class);
Emp emp=new Emp(10002,"Bill","123456");
Mockito.when(memberMockDao.getById(10002)).thenReturn(emp);
} @Test
public void normalTestWeakPswd() {
EmpService service=new EmpService(); // NullPointerException will be thrown out and case will fail
boolean actual=service.isWeakPswd(10001); Assert.assertSame(true, actual);
} @Test
public void testWeakPswd_ByMock_01() throws Exception {
EmpDao mockDao = Mockito.mock(EmpDao.class);
Emp emp=new Emp(10001,"Andy","111111");
Mockito.when(mockDao.getById(10001)).thenReturn(emp); // Use reflection replace dao with mockDao
EmpService service=new EmpService();
Field daoField = service.getClass().getDeclaredField("dao");
daoField.setAccessible(true);
daoField.set(service, mockDao); Assert.assertEquals(true, service.isWeakPswd(10001));
} @Test
public void testWeakPswd_ByMock_02() throws Exception { // Use reflection replace dao with mockDao
EmpService service=new EmpService();
Field daoField = service.getClass().getDeclaredField("dao");
daoField.setAccessible(true);
daoField.set(service, memberMockDao); Assert.assertEquals(true, service.isWeakPswd(10002));
} @Test
public void testWeakPswd_ByMock_03() throws Exception {
EmpDao mockDao = Mockito.mock(EmpDao.class);
Emp emp=new Emp(10003,"Cindy","Cindy");
Mockito.when(mockDao.getById(10003)).thenReturn(emp); // Use reflection replace dao with mockDao
EmpService service=new EmpService();
Field daoField = service.getClass().getDeclaredField("dao");
daoField.setAccessible(true);
daoField.set(service, mockDao); Assert.assertEquals(true, service.isWeakPswd(10003));
}
}

要测试的EmpService类:

package mockito;

public class EmpService {
private EmpDao dao; public EmpService() {
dao=new EmpDao();
} public boolean isWeakPswd(long empId) {
// roadlock which hinder running bacause of no environment
Emp emp=dao.getById(empId); // Real code need to be test,but unreachable because emp is null
if(emp.getPswd().equals("111111")) {
return true;
}else if(emp.getPswd().equals("123456")) {
return true;
}else if(emp.getName().equals(emp.getPswd())) {
return true;
}else {
return false;
}
}
}

因伤不能上阵的EmpDao类:

package mockito;

public class EmpDao {
public Emp getById(long id) {
// Access auth/redis/db to get a real emp,but it is difficult to set up environment in test,so return null
return null;
}
}

实体类Emp:

package mockito;

public class Emp {
private long id;
private String name;
private String pswd; public Emp() { } public Emp(long id,String name,String pswd) {
this.id=id;
this.name=name;
this.pswd=pswd;
} public long getId() {
return id;
} public void setId(long id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getPswd() {
return pswd;
} public void setPswd(String pswd) {
this.pswd = pswd;
}
}

要使用Mockito,可以在pom.xml里进行如以下红字部分设置:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com</groupId>
<artifactId>logbackCfg</artifactId>
<version>0.0.1-SNAPSHOT</version> <properties>
<java.version>1.8</java.version>
</properties> <dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.11</version>
</dependency> <dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.11</version>
</dependency> <dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.1.0</version>
<scope>test</scope>
</dependency> <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>

</dependencies>
</project>

--2020年3月11日--

参考资料:http://www.voidcn.com/article/p-vekqzrow-btm.html

Mock与反射关系不小,这里是反射资料:https://blog.csdn.net/a745233700/article/details/82893076

反射资料2:https://www.sczyh30.com/posts/Java/java-reflection-1/

Mockito在JUnit测试中的使用的更多相关文章

  1. Junit测试中的setup和teardown 和 @before 和 @After 方法

    这几天做Junit测试接触到了setup和teardown两个方法,简单的可以这样理解它们,setup主要实现测试前的初始化工作,而teardown则主要实现测试完成后的垃圾回收等工作. 需要注意的是 ...

  2. Junit测试中找不到junit.framework.testcase

    在使用Junit进行测试时,出现如下问题: 找不到junit.framework.testcase 解决方法: 选中项目->属性->Java构建路径->库->添加外部jar 在 ...

  3. java Junit 测试中异常处理

    错误提示: junit.framework.AssertionFailedError: No tests found in错误解决办法 用junit Test运行后,出现如下的错误:junit.fra ...

  4. Eclipse中Junit测试中@Before不执行

    场景 在使用Junit进行单元测试时,一部分获取JPA的entityManager的代码将其放在了 @Before标注的方法中,这样每次执行@TEST标注的方法时会首先执行@Before标注的方法. ...

  5. Junit mockito解耦合测试

    Mock测试是单元测试的重要方法之一. 1.相关网址 官网:http://mockito.org/ 项目源码:https://github.com/mockito/mockito api:http:/ ...

  6. Javaspring+mybit+maven中实现Junit测试类

    在一个Javaspring+mybit+maven框架中,增加Junit测试类. 在测试类中遇到的一些问题,利用spring 框架时,里面已经有保密security+JWT设定的场合,在你的secur ...

  7. 在Eclipse中生成接口的JUnit测试类

    在Spring相关应用中,我们经常使用“接口” + “实现类” 的形式,为了方便,使用Eclipse自动生成Junit测试类. 1. 类名-new-Other-java-Junit-Junit Tes ...

  8. JUnit测试工具在项目中的用法

    0:33 2013/6/26 三大框架整合时为什么要对项目进行junit测试: |__目的是测试配置文件对不对,能跑通就可以进行开发了 具体测试步骤: |__1.对hibernate进行测试 配置hi ...

  9. Junit 4 测试中使用定时任务操作

    难度:测试中执行线程操作 package com.hfepc.job.dataCollection.test; import java.util.Date; import java.util.List ...

随机推荐

  1. GitLab 数据库

    访问 GitLab 数据库 步骤 用的 Docker Gitlab,首先进入容器 docker exec -it gitlab /bin/bash `` 找到数据库配置文件 ```bash /var/ ...

  2. 了解学习 Javascript, ES5 和 ES6之间的亲密关系

    什么是Javascript JavaScript一种动态类型.弱类型.基于原型的客户端脚本语言,用来给HTML网页增加动态功能.   JavaScript 的标准是 ECMAScript.截至 201 ...

  3. Vue组件通信之父传子

    一般情况下,子组件中无法直接使用父组件的变量.借助子组件的props选项可以实现这一点. 这里我将一个vue实例作为一个父组件: const app = new Vue({ el:'#div1', d ...

  4. 下载的附件名总乱码?你该去读一下 RFC 文档了!

    纸上得来终觉浅,绝知此事要躬行 Web 开发过程中,相信大家都遇到过附件下载的场景,其中,各浏览器下载后的文件名中文乱码问题或许一度让你苦恼不已. 网上搜索一下,大部分都是通过Request Head ...

  5. DB2数据库错误代码大全

    SQLCode SQLState 状态说明 000 00000 SQL语句成功完成 01xxx XXX SQL语句成功完成,但是有警告 +012 01545 未限定的列名被解释为一个有相互关系的引用 ...

  6. 如何隐藏win32 控制台程序的console窗口 2011-06-17 17:59

    加上 即可 // 隐藏窗口#pragma   comment(linker,   "/subsystem:\"windows\"  /entry:\"mainC ...

  7. GUAVA-ListenableFuture实现回调

    随着软件开发的不断进步,在实际的开发应用中,可能一次请求需要查询若干次数据库或者调用若干次第三方,按照传统的串行执行的话,会大大增加响应时间,无法满足业务需求,更无法满足用户迫切需要响应迅速的愿望.对 ...

  8. ganglia访问时出现"You don't have permission to access /ganglia/ on this server"

    安装ganglia后,访问浏览器出现"You don't have permission to access /ganglia/ on this server" 按照网络上的要求配 ...

  9. 使用openpyxl创建excel,设置不显示网格线

    最近在学openpyxl,想设置excel不显示网格线,试了好多种方法都不行,最后发现可以通过修改views文件来实现. 文件路径:虚拟目录\Lib\site-packages\openpyxl\wo ...

  10. springMVC入门(八)------拦截器

    简介 springMVC拦截器针对处理器映射器进行拦截配置 如果在某个处理器映射器中配置拦截,经过该处理器映射器映射成功的Handler最终使用该拦截器 由于springMVC支持配置多个处理器映射器 ...