背景

工作中经常用到单测,某对单测掌握的不好,所以趁此学习、总结一下。

主要参考:https://www.jianshu.com/p/0c2480b1709e、https://www.cnblogs.com/ljw-bim/p/9391770.html

一、不依赖外部方法的单测

1、待测试类

package com.shuimutong.demo.junit;

/**
* 无依赖方法
* @ClassName: NotStaticMethod
* @Description:(这里用一句话描述这个类的作用)
* @author: 水木桶
* @date: 2019年10月26日 上午10:37:09
* @Copyright: 2019 [水木桶] All rights reserved.
*/
public class NoRelayMethod {
public static int ADD_NUM = 2; public static int staticAddTwo(int num) {
return num + ADD_NUM;
} /**
* 非静态方法
* @param num
* @return
*/
public int notStaticAddTwo(int num) {
return num + ADD_NUM;
} /**
* 私有非静态方法
* @param num
* @return
*/
private int privateNotStaticAddTow(int num) {
return num + ADD_NUM;
}
}

2、单测类

package com.shuimutong.demo.junit;

import java.lang.reflect.Method;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner; /**
* 参照1:https://www.jianshu.com/p/0c2480b1709e
* 参照2:https://www.cnblogs.com/ljw-bim/p/9391770.html
* @ClassName: NoRelayMethodTest
* @Description:(这里用一句话描述这个类的作用)
* @author: 水木桶
* @date: 2019年10月26日 下午4:14:48
* @Copyright: 2019 [水木桶] All rights reserved.
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest({NoRelayMethod.class})
public class NoRelayMethodTest {
@InjectMocks
private NoRelayMethod noRelayMethod; //不需要mock,可以去除上面3个注解
@Test
public void staticAddTwo() {
int num = 3;
int result = NoRelayMethod.staticAddTwo(num);
Assert.assertTrue(result == (num + NoRelayMethod.ADD_NUM)); } //不需要mock,可以去除上面3个注解
@Test
public void notStaticAddTwo() {
int num = 1;
NoRelayMethod noRelayMethod = new NoRelayMethod();
int result = noRelayMethod.notStaticAddTwo(num);
Assert.assertTrue(result == (num + NoRelayMethod.ADD_NUM));
} //需要mock
//mock私有方法
@Test
public void privateNotStaticAddTow() throws Exception {
Method method = PowerMockito.method(NoRelayMethod.class, "privateNotStaticAddTow", int.class);
int num = 3;
Object res = method.invoke(noRelayMethod, 3);
System.out.println(res);
Assert.assertEquals(num + NoRelayMethod.ADD_NUM, res);
}
}

3、备注

staticAddTwo和notStaticAddTwo方法不需要RunWith、PrepareForTest、InjectMocks这3个注解。

privateNotStaticAddTow涉及到私有方法,需要前面那3个注解。

二、有依赖外部静态方法的单测

1、待测试类

package com.shuimutong.demo.junit;

/**
* 有依赖其他静态方法
* @ClassName: RelayMethod
* @Description:(这里用一句话描述这个类的作用)
* @author: 水木桶
* @date: 2019年10月26日 下午3:26:01
* @Copyright: 2019 [水木桶] All rights reserved.
*/
public class RelayStaticMethod {
public final static String DEFAULT_VAL = "defaultVal";
public final static String SIGNED = "signed"; /**
* 依赖静态方法的
* @param key
* @return
*/
public String checkAndCalc(String key) {
String returnVal = null;
String savedVal = RedisUtil.get(key);
if(savedVal == null || savedVal.length() < 1) {
returnVal = DEFAULT_VAL;
} else {
returnVal = savedVal + "-" + SIGNED;
}
return returnVal;
} }

1-1、依赖外部类

package com.shuimutong.demo.junit;

import java.util.UUID;

public class RedisUtil {
private static boolean INIT_STATE = false; public static String get(String key) {
if(INIT_STATE) {
return UUID.randomUUID().toString();
} else {
throw new NullPointerException("资源未初始化");
}
} }

2、单测类

package com.shuimutong.demo.junit;

import java.util.UUID;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner; @RunWith(PowerMockRunner.class)
//参考:https://www.jianshu.com/p/0c2480b1709e
//1、如果想要对某个类的静态方法进行mock,则必须在PrepareForTest后面加上相应的类名, 比如此例的RedisUtil.class。
@PrepareForTest({RedisUtil.class})
public class RelayStaticMethodTest {
/**
* mock依赖的静态方法
*/
@Test
public void checkAndCalc() {
String key1 = "jack";
String key2 = "john";
String val2 = UUID.randomUUID().toString(); //2、在对该类的某个方法进行mock之前,还必须先对整个类进行mock
PowerMockito.mockStatic(RedisUtil.class);
PowerMockito.when(RedisUtil.get(Mockito.eq(key1))).thenReturn(null);
PowerMockito.when(RedisUtil.get(Mockito.eq(key2))).thenReturn(val2); RelayStaticMethod relayMethod = new RelayStaticMethod();
String res = relayMethod.checkAndCalc(key1);
System.out.println("res:" + res);
Assert.assertEquals(RelayStaticMethod.DEFAULT_VAL, res); res = relayMethod.checkAndCalc(key2);
System.out.println("res:" + res);
Assert.assertTrue(res.contains(RelayStaticMethod.SIGNED));
} }

2-1、运行结果

res:defaultVal
res:e76dc3b8-fcf5-42b8-9f79-1d308d137514-signed

三、有依赖外部非静态方法的单测

1、待测试类

package com.shuimutong.demo.junit;

/**
* 参照1:https://www.jianshu.com/p/0c2480b1709e
* 参照2:https://www.cnblogs.com/ljw-bim/p/9391770.html
* @ClassName: UserController
* @Description:(这里用一句话描述这个类的作用)
* @author: 水木桶
* @date: 2019年10月26日 下午4:14:30
* @Copyright: 2019 [水木桶] All rights reserved.
*/
public class UserController {
private UserService userService = new UserService(); public User saveUser(String name) {
return userService.save(name);
}
}

1-1、依赖非静态类

package com.shuimutong.demo.junit;

public class UserService {
public User save(String name) {
System.out.println("UserService--save--name:" + name);
User u = new User(name);
u.setId((long)(Math.random() * 1000) + 2);
return u;
}
}

1-2、相关类User

package com.shuimutong.demo.junit;

public class User {
private long id;
private String name; public User(String name) {
this.name = name;
}
public User() {
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + "]";
}
}

2、单测类

package com.shuimutong.demo.junit;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner; /**
* 参照1:https://www.jianshu.com/p/0c2480b1709e
* 参照2:https://www.cnblogs.com/ljw-bim/p/9391770.html
* @ClassName: UserControllerTest
* @Description:(这里用一句话描述这个类的作用)
* @author: 水木桶
* @date: 2019年10月26日 下午4:13:51
* @Copyright: 2019 [水木桶] All rights reserved.
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest({UserController.class})
public class UserControllerTest {
@Mock
private UserService userService;
@InjectMocks
private UserController userController; @Test
public void saveUser() {
String name = "jack";
//执行userService的实际方法
PowerMockito.when(userService.save(Mockito.anyString())).thenCallRealMethod();
User returnUser = userController.saveUser(name);
System.out.println("returnUser:" + returnUser);
Assert.assertTrue(returnUser.getId() > 1); long id = 1L;
User u1 = new User(name);
u1.setId(id);
System.out.println("u1:" + u1);
//mock userService的方法
Mockito.when(userService.save(name)).thenReturn(u1);
returnUser = userController.saveUser(name);
//verify验证mock次数
Mockito.verify(userService, Mockito.times(2)).save(name);
Assert.assertEquals(id, returnUser.getId());
Assert.assertEquals(u1, returnUser);
System.out.println("returnUser:" + returnUser);
}
}

2-1、执行结果

UserService--save--name:jack
returnUser:User [id=51, name=jack]
u1:User [id=1, name=jack]
UserService--save--name:jack
returnUser:User [id=1, name=jack]

四、相关环境

1、依赖jar

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>2.0.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.2</version>
<scope>test</scope>
</dependency>

2、源码地址

https://gitee.com/simpleha/useDemo/tree/master/junit

Mock、Powermock使用汇总的更多相关文章

  1. 单元测试系列:Mock工具Jmockit使用介绍

    更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢! 原文链接:http://www.cnblogs.com/zishi/p/6760272.html Mock工具Jm ...

  2. 单元测试系列之二:Mock工具Jmockit实战

    更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢! 原文链接:http://www.cnblogs.com/zishi/p/6760272.html Mock工具Jm ...

  3. 有效使用Mock编写java单元测试

    Java单元测试对于开发人员质量保证至关重要,尤其当面对一团乱码的遗留代码时,没有高覆盖率的单元测试做保障,没人敢轻易对代码进行重构.然而单元测试的编写也不是一件容易的事情,除非使用TDD方式,否则编 ...

  4. spring boot 测试用例

    junit 是一个面向于研发人员使用的轻量的测试模块,适合做单元测试.而testng百度后发现更强大,可以做功能测试,但对于我这种RD,貌似junit足沟了呢! java Mock PowerMock ...

  5. Mock之easymock, powermock, and mockito

    easymock, powermock, and mockito Easymock Class Mocking Limitations To be coherent with interface mo ...

  6. 用PowerMock mock 由工厂方法产生的对象

    有些对象需要mock的对象是由工厂方法产生出来的,而工厂方法一般是静态方法,这时候就需要同时mock工厂方法及对象 被测方法: public class EmployeeServiceFactory ...

  7. 用PowerMock spy mock private方法

    在实际的工作中,经常碰到只需要mock一个类的一部分方法,这时候可以用spy来实现. 被测类: public class EmployeeService { public boolean exist( ...

  8. 用PowerMock mock static方法

    在编写代码时,经常需要调用别人已经写好的工具类,而这些工具提供的方法经常是static方法,在这里,直接贴出<PowerMock实战手册>中的例子 待测试方法: public class ...

  9. 用PowerMock mock 临时变量

    在开发时,经常遇到这种情况,被测试方法所调用的类不是通过构造注入的,而是通过临时new出来的,如下面待测方法: public class EmployeeService { private Emplo ...

随机推荐

  1. linux驱动由浅入深系列:高通sensor架构实例分析之二(驱动代码结构)【转】

    本文转载自:https://blog.csdn.net/radianceblau/article/details/73498303 本系列导航: linux驱动由浅入深系列:高通sensor架构实例分 ...

  2. vs2015 项目调试出现未能加载文件或程序集“Antlr3.Runtime”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。 (异常来自 HRESULT:0x80131040)

    今天在调试项目不知道怎么了,突然就报未能加载文件或程序集“Antlr3.Runtime”或它的某一个依赖项.找到的程序集清单定义与程序集引用不匹配. (异常来自 HRESULT:0x80131040) ...

  3. EChart 标题 title 样式,x轴、y轴坐标显示,调整图表位置等

    示例里工作一般情况是够用了,更复杂的可以查询教程: title 官方解说:http://echarts.baidu.com/option.html#title 坐标相关: X轴:http://echa ...

  4. ASP.NET LinqDataSource数据绑定后,遇到[MissingMethodException: 没有为该对象定义无参数的构造函数。]问题。

    问题出现的情形:LinqDataSource数据绑定到DetailsView或GridView均出错,错误如下: “/”应用程序中的服务器错误. 没有为该对象定义无参数的构造函数. 说明: 执行当前 ...

  5. [Sw] Swoole 生态迷局,基于 Swoole 的第 109 框架

    这两天,又一全栈式 Swoole 协程框架面世了 - hyperf,实现思路是我内心点了赞同的,就集成现有 PHP 生态优质组件到 Swoole 的协程中来. 有人想到,为什么不是 Swoole 集成 ...

  6. Spring Boot 的Logback

    Spring Boot 默认使用Logback记录日志 Spring Boot starter 都会默认引入spring-boot-starter-logging,不需要再引入 日志级别从高到低:TR ...

  7. 升级libstdc++、libgcc_s.so、libc.so.6

    参考资料:https://blog.csdn.net/ltl451011/article/details/7763892/ https://blog.csdn.net/na_beginning/art ...

  8. PHP ob_gzhandler的理解

    PHP ob_gzhandler的理解那么对于我们这些没有开启mod_deflate模块的主机来说,就只能采用ob_gzhandler函数来压缩了,它的压缩效果和mod_deflate相比,相差很小, ...

  9. PowerDNS + PowerDNS-Admin

    一.基础配置 1.1 环境说明 Centos 7.5.1804 PDNS MariaDB 1.2 关闭防火墙和 selinux setenforce sed -i 's/SELINUX=enforci ...

  10. Java的集合类之 map 接口用法

    Map接口不是Collection接口的继承.而是从自己的用于维护键-值关联的接口层次结构入手.按定义,该接口描述了从不重复的键到值的映射. 我们可以把这个接口方法分成三组操作:改变.查询和提供可选视 ...