Java单元测试
单元测试:只测试系统中最原子化的行为单元的自动化测试–测试核心逻辑
简单设计4原则:
测试变绿–测试通过
没有重复–代码没有重复
揭示意图–测试什么功能
最少元素
单元测试策略:变红(单元测试)->变绿(烂代码)->重构(优化)
测试替身
SUT System Under Test
DOC Dependence On Component
Mockito
- Mock – 不关心数据的输入和输出,验证mock的方法是否被调用过
- Stub – 数据的伪造,替换真实数据
- Spy
采用Mockito和PowerMockito进行单元测试
以下单元测试案例执行基于:
Spring Boot 1.5.6.RELEASE
Mockito 2.25.1
PowerMockito 2.0.2
Jacoco 0.8.2
1、属性注入
1 2 3
| import org.springframework.test.util.ReflectionTestUtils;
ReflectionTestUtils.setField(被测试类, "属性名", 属性实际值);
|
2、调用方法中有 new 操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @RunWith(PowerMockRunner.class)
@Test @PrepareForTest(value = {被测试类.class, 需要new的类.class})
@RunWith(PowerMockRunner.class) public class MyTest { @Test @PrepareForTest(value = {Test.class, Date.class}) public void test() { Date date = PoweerMockito.mock(Date.class);
try { PowerMockito.whenNew(Date.class).withNoArguments().thenReturn(date); } catch (Exception e) { e.printStackTrace(); } } }
|
3、静态方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @RunWith(PowerMockRunner.class)
@Test @PrepareForTest(value = {被测试类.class, 需要使用的静态方法所属类.class})
@RunWith(PowerMockRunner.class) public class MyTest { @Test @PrepareForTest(value = {Test.class, EncodeUtils.class}) public void test() { PowerMockito.mockStatic(EncodeUtils.class); PowerMockito.when(EncodeUtils.decript(passwd, key)).thenReturn(plainPwd); } }
|
4、一般方法
1 2 3 4 5 6 7 8
| doReturn(xxx).when(mockXX).executeMethod(); doThrow(Exception.class) doNothing()
verify(mockXX, times(调用次数)).executeMethod()
|
5、单元测试使用PowerMockito时,jacoco覆盖率无法兼容解决
参考 https://github.com/powermock/powermock-examples-maven/blob/master/jacoco-offline/pom.xml
生成html覆盖报告,可以修改为如下内容:
1 2 3 4 5 6 7 8 9 10 11
| <execution> <id>report</id> <phase>prepare-package</phase> <goals> <goal>report</goal> </goals> <configuration> <dataFile>${project.build.directory}/coverage.exec</dataFile> <outputDirectory>${basedir}/target/coverage-reports</outputDirectory> </configuration> <execution>
|