Skip to content

Commit 7418819

Browse files
committed
[feat]使用 PowerMockRunner 和 Mockito 编写单元测试用例
1 parent 572b7e3 commit 7418819

File tree

3 files changed

+166
-181
lines changed

3 files changed

+166
-181
lines changed

Diff for: README.md

+5-4
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,13 @@
3030
### 进阶
3131

3232
1. Bean映射工具 :[Bean映射工具之Apache BeanUtils VS Spring BeanUtils](./docs/advanced/Apache-BeanUtils-VS-SpringBean-Utils.md)[5种常见Bean映射工具的性能比对](./docs/advanced/Performance-of-Java-Mapping-Frameworks.md)
33-
3. [如何在 Spring/Spring Boot 中做参数校验?](./docs/spring-bean-validation.md)
33+
3. [如何在 Spring/Spring Boot 中优雅地做参数校验?](./docs/spring-bean-validation.md)
34+
3. [使用 PowerMockRunner 和 Mockito 编写单元测试用例](./docs/PowerMockRunnerAndMockito.md)
3435
4. [5分钟搞懂如何在Spring Boot中Schedule Tasks](./docs/advanced/SpringBoot-ScheduleTasks.md)
3536
5. [新手也能看懂的 Spring Boot 异步编程指南](./docs/advanced/springboot-async.md)
36-
7. [Kafka 入门+SpringBoot整合Kafka系列](https://github.com/Snailclimb/springboot-kafka)
37-
8. [超详细,新手都能看懂 !使用Spring Boot+Dubbo 搭建一个分布式服务](./docs/advanced/springboot-dubbo.md)
38-
9. [从零入门 !Spring Security With JWT(含权限验证)](https://github.com/Snailclimb/spring-security-jwt-guide)
37+
6. [Kafka 入门+SpringBoot整合Kafka系列](https://github.com/Snailclimb/springboot-kafka)
38+
7. [超详细,新手都能看懂 !使用Spring Boot+Dubbo 搭建一个分布式服务](./docs/advanced/springboot-dubbo.md)
39+
8. [从零入门 !Spring Security With JWT(含权限验证)](https://github.com/Snailclimb/spring-security-jwt-guide)
3940

4041
### 补充
4142

Diff for: docs/PowerMockRunnerAndMockito.md

+161
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
单元测试可以提高测试开发的效率,减少代码错误率,提高代码健壮性,提高代码质量。在 Spring 框架中常用的两种测试框架:`PowerMockRunner``SpringRunner` 两个单元测试,鉴于 `SpringRunner` 启动的一系列依赖和数据连接的问题,推荐使用 `PowerMockRunner`,这样能有效的提高测试的效率,并且其提供的 API 能覆盖的场景广泛,使用方便,可谓是 Java 单元测试之模拟利器。
2+
3+
## 1. PowerMock 是什么?
4+
5+
`PowerMock` 是一个 Java 模拟框架,可用于解决通常认为很难甚至无法测试的测试问题。使用 `PowerMock`,可以模拟静态方法,删除静态初始化程序,允许模拟而不依赖于注入,等等。`PowerMock` 通过在执行测试时在运行时修改字节码来完成这些技巧。`PowerMock` 还包含一些实用程序,可让您更轻松地访问对象的内部状态。
6+
7+
举个例子,你在使用 `Junit` 进行单元测试时,并不想让测试数据进入数据库,怎么办?这个时候就可以使用 `PowerMock`,拦截数据库操作,并模拟返回参数。
8+
9+
## 2. PowerMock 包引入
10+
11+
```xml
12+
<!-- 单元测试 依赖-->
13+
<dependency>
14+
<groupId>org.powermock</groupId>
15+
<artifactId>powermock-core</artifactId>
16+
<version>2.0.2</version>
17+
<scope>test</scope>
18+
</dependency>
19+
<dependency>
20+
<groupId>org.mockito</groupId>
21+
<artifactId>mockito-core</artifactId>
22+
<version>2.23.0</version>
23+
</dependency>
24+
<dependency>
25+
<groupId>org.powermock</groupId>
26+
<artifactId>powermock-module-junit4</artifactId>
27+
<version>2.0.4</version>
28+
<scope>test</scope>
29+
</dependency>
30+
<dependency>
31+
<groupId>org.powermock</groupId>
32+
<artifactId>powermock-api-mockito2</artifactId>
33+
<version>2.0.2</version>
34+
<scope>test</scope>
35+
</dependency>
36+
<dependency>
37+
<groupId>com.github.jsonzou</groupId>
38+
<artifactId>jmockdata</artifactId>
39+
<version>4.3.0</version>
40+
</dependency>
41+
```
42+
43+
## 3. 重要注解说明
44+
45+
```java
46+
@RunWith(PowerMockRunner.class) // 告诉JUnit使用PowerMockRunner进行测试
47+
@PrepareForTest({RandomUtil.class}) // 所有需要测试的类列在此处,适用于模拟final类或有final, private, static, native方法的类
48+
@PowerMockIgnore("javax.management.*") //为了解决使用powermock后,提示classloader错误
49+
```
50+
51+
## 4. 使用示例
52+
53+
### 4.1 模拟接口返回
54+
55+
首先对接口进行 mock,然后录制相关行为
56+
57+
```java
58+
InterfaceToMock mock = Powermockito.mock(InterfaceToMock.class)
59+
Powermockito.when(mock.method(Params…)).thenReturn(value)
60+
Powermockito.when(mock.method(Params..)).thenThrow(Exception)
61+
```
62+
63+
### 4.2 设置对象的 private 属性
64+
65+
需要使用 `Whitebox` 向 class 或者对象中赋值。
66+
67+
如我们已经对接口尽心了 mock,现在需要将此 mock 加入到对象中,可以采用如下方法:
68+
69+
```java
70+
Whitebox.setInternalState(Object object, String fieldname, Object… value);
71+
```
72+
73+
其中 object 为需要设置属性的静态类或对象。
74+
75+
### 4.3 模拟构造函数
76+
77+
对于模拟构造函数,也即当出现 `new InstanceClass()` 时可以将此构造函数拦截并替换结果为我们需要的 mock 对象。
78+
79+
注意:使用时需要加入标记:
80+
81+
```java
82+
@RunWith(PowerMockRunner.class)
83+
@PrepareForTest({ InstanceClass.class })
84+
@PowerMockIgnore("javax.management.\*")
85+
86+
Powermockito.whenNew(InstanceClass.class).thenReturn(Object value)
87+
```
88+
89+
##### 4.4 模拟静态方法
90+
91+
模拟静态方法类似于模拟构造函数,也需要加入注释标记。
92+
93+
```java
94+
@RunWith(PowerMockRunner.class)
95+
@PrepareForTest({ StaticClassToMock.class })
96+
@PowerMockIgnore("javax.management.\*")
97+
98+
Powermockito.mockStatic(StaticClassToMock.class);
99+
Powermockito.when(StaticClassToMock.method(Object.. params)).thenReturn(Object value)
100+
```
101+
102+
##### 4.5 模拟 final 方法
103+
104+
Final 方法的模拟类似于模拟静态方法。
105+
106+
```java
107+
@RunWith(PowerMockRunner.class)
108+
@PrepareForTest({ FinalClassToMock.class })
109+
@PowerMockIgnore("javax.management.\*")
110+
111+
Powermockito.mockStatic(FinalClassToMock.class);
112+
Powermockito.when(StaticClassToMock.method(Object.. params)).thenReturn(Object value)
113+
```
114+
115+
### 4.6 模拟静态类
116+
117+
模拟静态类类似于模拟静态方法。
118+
119+
### 4.7 使用 spy 方法避免执行被测类中的成员函数
120+
121+
如被测试类为:TargetClass,想要屏蔽的方法为 targetMethod.
122+
123+
```java
124+
1PowerMockito.spy(TargetClass.class);
125+
126+
2Powemockito.when(TargetClass.targetMethod()).doReturn()
127+
128+
3) 注意加入
129+
130+
@RunWith(PowerMockRunner.class)
131+
@PrepareForTest(DisplayMoRelationBuilder.class)
132+
@PowerMockIgnore("javax.management.*")
133+
```
134+
135+
### 4.8 参数匹配器
136+
137+
有时我们在处理 `doMethod(Param param)` 时,不想进行精确匹配,这时可以使用 `Mockito` 提供的模糊匹配方式。
138+
139+
如:`Mockito.anyInt()``Mockito.anyString()`
140+
141+
### 4.9 处理 public void 型的静态方法
142+
143+
```java
144+
Powermockito.doNothing.when(T class2mock, String method, <T>… params>
145+
```
146+
147+
## 5. 单元测试用例可选清单
148+
149+
输入数据验证:这些检查通常可以对输入到应用程序系统中的数据采用。
150+
151+
- 必传项测试
152+
- 唯一字段值测试
153+
- 空值测试
154+
- 字段只接受允许的字符
155+
- 负值测试
156+
- 字段限于字段长度规范
157+
- 不可能的值
158+
- 垃圾值测试
159+
- 检查字段之间的依赖性
160+
- 等效类划分和边界条件测试
161+
- 错误和异常处理测试单元测试可以提高测试开发的效率,减少代码错误率,提高代码健壮性,提高代码质量。在 Spring 框架中常用的两种测试框架:PowerMockRunnerSpringRunner 两个单元测试,鉴于 SpringRunner 启动的一系列依赖和数据连接的问题,推荐使用 PowerMockRunner,这样能有效的提高测试的效率,并且其提供的 API 能覆盖的场景广泛,使用方便,可谓是 Java 单元测试之模拟利器。

Diff for: docs/basis/PowerMockRunnerAndMockito.md

-177
This file was deleted.

0 commit comments

Comments
 (0)