单元测试-Junit-Mockit-PowerMock
0. Junit5
1. Junit4
//手动命令行测试
java -cp /usr1/junit:/usr1/cdncms/lib/* org.junit.runner.JUnitCore com.test.DomainServiceTest
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
1.0 执行报错java.lang.VerifyError: Expecting a stackmap frame at branch target 122
增加配置项: windsows-->installJREs-->edit --> VM arguments --> 增加 -noverify
1.1 Junit注解
@BeforeClass 针对所有测试,只执行一次,且必须为static void
@Before: 初始化方法
@Test: 测试方法,在这里可以测试期望异常和超时时间
@After: 释放资源
@AfterClass: 针对所有测试,只执行一次,且必须为static void
@Ignore: 忽略的测试方法
一个单元测试用例执行顺序为: @BeforeClass –> @Before –> @Test –> @After –> @AfterClass
每一个测试方法的调用顺序为: @Before –> @Test –> @After
1.2 Assert类
assertEquals(boolean expected, boolean actual) 检查两个变量或者等式是否平衡
assertFalse(boolean condition) 检查条件是假的
assertNotNull(Object object) 检查对象不是空的
assertNull(Object object) 检查对象是空的
assertTrue(boolean condition) 检查条件为真
fail() 在没有报告的情况下使测试不通过
junit匹配抛出异常
@Test(expected = IllegalArgumentException.class)
public void canVote_throws_IllegalArgumentException_for_zero_age() {.......}
2. Mockito--创建 Mock 对象并且定义它的行为
2.1
a). 静态方法: import static org.mockito.Mockito.*;
b). 验证方法是否调用: verify(test, times(2)).getUniqueId();
2.2 示例
基本用法: (无法对static method和private method进行插桩)
when(cls.methodName(args)).thenReturn(args) //对指定语句进行插桩
when(cls.methodName(args)).thenThrow(Exception) //抛出异常
1、 基本示例
LinkedList mockedList = mock(LinkedList.class);
//插桩
when(mockedList.get(0)).thenReturn("first");
when(mockedList.get(1)).thenThrow(new RuntimeException());
System.out.println(mockedList.get(0)); //输出"first"
System.out.println(mockedList.get(1)); //抛出异常
System.out.println(mockedList.get(999)); //输出 null , 因为get(999)未插桩
2、 插桩时可用 Matcher.anyString()/anyInt() 等进行入参匹配
when(mockedList.get(anyInt())).thenReturn("element");
3、 针对void方法抛出异常
doThrow(new RuntimeException()).when(mockedList).clear();
4、 针对void方法插桩
doNothing().when(spy).clear();
3. PowerMock--插桩,static/final/private
3.1 原理
//两个重要注解 -- 使用ASM生成代理类进行mock
@RunWith(PowerMockRunner.class) //通用配置
@PrepareForTest( { YourClassWithEgStaticMethod.class }) //需要powermock处理的class,static、final、私有方法等功能
1) 例如:去除'final方法的final标识,在静态方法的最前面加入自己的虚拟实现等。
2) 如果mock的是系统类的final/static,PowerMock会修改调用系统类的class文件,以满足mock需求。
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<powermock.version>1.7.1</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>
//通过PowerMock创建一个虚拟对象
InterfaceToMock mock = Powermockito.mock(InterfaceToMock.class)
//value为你想要让这个method返回的值
Powermockito.when(mock.method(Params…)).thenReturn(valueToReturn)
//如果这个方法返回值为空,则上面的写法会报错,可采用下面的写法
Powermockito.when(mock, “methodName”, Object… params).thenReturn(valueToReturn)
// 也可以采用下面的写法,和上面的一样的效果
Powermockito.doReturn(valueToReturn).when(mock, “methodName”, Object… params)
//这样写也行,适合返回值为void的方法
Powermockito.doReturn(valueToReturn).when(mock).methodName(Object… params)
//你也可以让方法抛异常
Powermockito.when(mock.method(Params..)).thenThrow(new OMSException(“oms”))
//你可以让方法每一次返回的结果都不一样,下面的例子第一次正常返回,第二次调用抛异常
Powermockito.when(mock.method(Params..)).thenReturn(valueToReturn).thenThrow(new OMSException(“some Exception”))
//如果方法返回值为void,不能用thenReturn,要用doThing()
Powermockito.doNothing().when(mock.method(Params…))
3.2 示例1-mock static方法
public class IdGenerator {
public static long generateNewId() {
return 0L;
}
}
public class ClassUnderTest {
public long methodToTest() {
final long id = IdGenerator.generateNewId();
return id;
}
}
@RunWith(PowerMockRunner.class)
@PrepareForTest(IdGenerator.class)
public class TestStatic {
@Test
public void testCallInternalInstance() throws Exception {
PowerMockito.mockStatic(IdGenerator.class);
// 在这个测试用例中,当generateNewId()每次被调用时,都会返回15
PowerMockito.when(IdGenerator.generateNewId()).thenReturn(15L);
Assert.assertEquals(15L, new ClassUnderTest().methodToTest());
}
}
3.2 示例2-模拟构造方法
public class ClassUnderTest {
public boolean createDirectoryStructure(String directoryPath) {
File directory = new File(directoryPath);
if (directory.exists()) {
String msg = "\"" + directoryPath + "\" 已经存在.";
throw new IllegalArgumentException(msg);
}
return directory.mkdirs();
}
}
@RunWith(PowerMockRunner.class)
@PrepareForTest(ClassUnderTest.class)
public class TestConstruction {
//模拟构造函数
@Test
public void createDirectoryStructureWhenPathDoesntExist() throws Exception {
final String directoryPath = "seemygod";
//创建File的模拟对象
File directoryMock = mock(File.class);
//在当前测试用例下,当出现new File("seemygod")时,就返回模拟对象
whenNew(File.class).withArguments(directoryPath).thenReturn(directoryMock);
//当调用模拟对象的exists时,返回false
when(directoryMock.exists()).thenReturn(false);
//当调用模拟对象的mkdirs时,返回true
when(directoryMock.mkdirs()).thenReturn(true);
assertTrue(new ClassUnderTest().createDirectoryStructure(directoryPath));
//验证new File(directoryPath); 是否被调用过
verifyNew(File.class).withArguments(directoryPath);
}
}
3.4 用例3-模拟私有以及 Final 方法
public class PrivatePartialMockingExample {
public String methodToTest() {
return methodToMock("input");
}
private String methodToMock(String input) {
return "REAL VALUE = " + input;
}
}
import static org.powermock.api.mockito.PowerMockito.*;
@RunWith(PowerMockRunner.class)
@PrepareForTest(PrivatePartialMockingExample.class)
public class PrivatePartialMockingExampleTest {
@Test
public void demoPrivateMethodMocking() throws Exception {
final String expected = "TEST VALUE";
final String nameOfMethodToMock = "methodToMock";
final String input = "input";
PrivatePartialMockingExample underTest = spy(new PrivatePartialMockingExample());
//模拟私有方法
when(underTest, nameOfMethodToMock, input).thenReturn(expected);
assertEquals(expected, underTest.methodToTest());
verifyPrivate(underTest).invoke(nameOfMethodToMock, input);
}
}
3.5 用例4-mock系统类的静态和final方法
public class ClassUnderTest {
public boolean callSystemFinalMethod(String str) {
return str.isEmpty();
}
public String callSystemStaticMethod(String str) {
return System.getProperty(str);
}
}
$RunWith(PowerMockRunner.class)
public class TestClassUnderTest {
$Test
$PrepareForTest(ClassUnderTest.class)
public void testCallSystemStaticMethod() {
ClassUnderTest underTest = new ClassUnderTest();
PowerMockito.mockStatic(System.class);
PowerMockito.when(System.getProperty("aaa")).thenReturn("bbb");
Assert.assertEquals("bbb", underTest.callJDKStaticMethod("aaa"));
}
}
3.6 用例-PowerMock处理注解
//PushMsgPostProcessorImpl 是要测试的类,它有两个注解注入的类变量如下:
@Resource
private IMsgToUserService msgToUserService;
//则测试类中可以使用下面的方法注入
@Mock
private IMsgToUserService msgToUserService;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
pushMsgPostProcessor = new PushMsgPostProcessorImpl();
//给注解的private变量塞一个值
ReflectionTestUtils.setField(pushMsgPostProcessor, "msgToUserService", msgToUserService);
}
3.10 模拟异常
3.10.1 抛出异常-不带参数
//PowerMockito.when(IOUtils.xMLReader()).thenThrow(SAXException.class);
public class IOUtils {
public static String xMLReader() throws SAXException {
return "abc";
}
}
3.10.2 抛出异常-待参数的异常
//PowerMockito.doThrow(new SAXException()).when(IOUtils.class);
public class IOUtils {
public static String xMLReader(SAXReader reader) throws SAXException {
System.out.println("IOUtils.xMLReader");
if (null == reader) {
throw new SAXException();
}
return "abc";
}
}
单元测试-Junit-Mockit-PowerMock的更多相关文章
- Java单元测试(Junit+Mock+代码覆盖率)---------转
Java单元测试(Junit+Mock+代码覆盖率) 原文见此处 单元测试是编写测试代码,用来检测特定的.明确的.细颗粒的功能.单元测试并不一定保证程序功能是正确的,更不保证整体业务是准备的. 单元测 ...
- Spring注解AOP及单元测试junit(6)
2019-03-10/20:19:56 演示:将xml配置方式改为注解方式 静态以及动态代理推荐博客:https://blog.csdn.net/javazejian/article/details/ ...
- Java学习——单元测试JUnit
Java学习——单元测试JUnit 摘要:本文主要介绍了什么是单元测试以及怎么进行单元测试. 部分内容来自以下博客: https://www.cnblogs.com/wxisme/p/4779193. ...
- Springboot单元测试Junit深度实践
Springboot单元测试Junit深度实践 前言 单元测试的好处估计大家也都知道了,但是大家可以发现在国内IT公司中真正推行单测的很少很少,一些大厂大部分也只是在核心产品推广单测来保障质量,今天这 ...
- 面试题_89_to_92_单元测试 JUnit 面试题
89)如何测试静态方法?(答案)可以使用 PowerMock 库来测试静态方法. 90)怎么利用 JUnit 来测试一个方法的异常?(答案) 91)你使用过哪个单元测试库来测试你的 Java 程序?( ...
- Java单元测试(Junit+Mock+代码覆盖率)
微信公众号[程序员江湖] 作者黄小斜,斜杠青年,某985硕士,阿里 Java 研发工程师,于 2018 年秋招拿到 BAT 头条.网易.滴滴等 8 个大厂 offer,目前致力于分享这几年的学习经验. ...
- java单元测试(Junit)
Eclipse最基本的模块测试 1:首先创建一个java工程,在工程中创建一个被单元测试的Student数据类,如下: package UnitTest; public class Student { ...
- Android:单元测试Junit的配置
在实际开发中,开发android软件的过程需要不断地进行测试.而使用Junit测试框架,侧是正规Android开发的必用技术,在Junit中可以得到组件,可以模拟发送事件和检测程序处理的正确性.... ...
- Java 单元测试(Junit)
在有些时候,我们需要对我们自己编写的代码进行单元测试(好处是,减少后期维护的精力和费用),这是一些最基本的模块测试.当然,在进行单元测试的同时也必然得清楚我们测试的代码的内部逻辑实现,这样在测试的时候 ...
- JAVA单元测试Junit
1.为什么要用Junit 做了很多项目,几乎没怎么用过Java的单元测试,是因为它没有用吗?显然不是,是自己的开发方式太不规范!对于大型的软件项目,单元测试不仅有效实用,还非常有必要!它能够测试每个方 ...
随机推荐
- 抽象类(abstract)【转】
抽象类(abstract) abstract修饰符可以和类.方法.属性.索引器及事件一起使用.在类声明中使用abstract修饰符以指示某个类只能是其它类的基类.标记为抽象或包含在抽象类中的成员必须通 ...
- 洛谷P3784 [SDOI2017]遗忘的集合(生成函数)
题面 传送门 题解 生成函数这厮到底还有什么是办不到的-- 首先对于一个数\(i\),如果存在的话可以取无限多次,那么它的生成函数为\[\sum_{j=0}^{\infty}x^{ij}={1\ove ...
- Python中的Numpy包
通过本次学习你可以掌握Numpy Numpy介绍(获取地址)更多Numpy函数 numpy的主要对象是同质多维数组.也就是在一个元素(通常是数字)表中,元素的类型都是相同的. numpy的数组类被成为 ...
- P1903 [国家集训队]数颜色 / 维护队列 带修改的莫队
\(\color{#0066ff}{ 题目描述 }\) 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会向你发布如下指令: 1. Q L R代表询问你从第L支 ...
- P3356 火星探险问题
\(\color{#0066ff}{题目描述}\) 火星探险队的登陆舱将在火星表面着陆,登陆舱内有多部障碍物探测车.登陆舱着陆后,探测车将离开登陆舱向先期到达的传送器方向移动.探测车在移动中还必须采集 ...
- php屏蔽错误消息
定义和用法: error_reporting() 设置 PHP 的报错级别并返回当前级别. 函数语法: error_reporting(report_level) 如果参数 level 未指定,当前报 ...
- Gym - 101845F 最大流
The UN finals are here!, the coaches/ex-coaches team is creating a new exciting contest to select wh ...
- [USACO5.4]奶牛的电信Telecowmunication 最小割
题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流.这些机器用如下的方式发送电邮:如果存在一个由c台电脑组成的序列a1,a2,...,a(c),且a1与a2相 ...
- 前三次OO作业总结
一.作业总结 前三次的任务都是表达式求导.这是我在高中就思考过的问题,但是很久都没有付诸实践,直到学习了"类"这个强大的工具.还有正则表达式,如果能适当使用,则不失为一个字符串格式 ...
- Java实现微信小程序支付(支付,提现,退款)
1.添加WXpayCommon类用以具体实现功能,代码如下: package com.karat.cn.wxCommon; import java.io.IOException; import jav ...