Java单元测试框架——Mockito

一、建立测试目录

测试包类路径与被测试包类保持一致

二、建立测试类

类名在被测试类名后面加上Test

(一)配置文件

1、pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>

Mockito是一个流行的Mocking(模拟测试)框架,通过使用Mocking框架,可以尽可能使unit test独立。

(二)构建测试类

实例化被测试类对象

1
private BGWorkStorage bgWorkStorage = new BGWorkStorage();

模拟变量

1
2
3
4
5
6
7
8
9
10
@Mock
private IBGControlManage bgControlManage;
@Mock
private IBGSeqManage bgSeqManage;
@Mock
private IBGWorkManage bgWorkManage;
@Mock
private ThreadLocal<Date> lastInsertDate = new ThreadLocal<>();
@Mock
private ThreadLocal<Integer> currentStep = new ThreadLocal<>();

定义方法内部用到的返回结果

1
2
3
4
private List<UsersBo> userBoList;
private List<AcctAccountRelationBo> acctAccountRelationBoList;
private List<AcctAccountBo> acctAccountBoList;
private List<BillDetailItemBo> queryBillDetailItemList;

初始化mock变量

1
2
3
4
5
6
7
8
9
10
11
@BeforeMethod
public void setUp() throws Exception{
// 初始化
MockitoAnnotations.initMocks(this);
ReflectionTestUtils.setField(AopTargetUtils.getTarget(genBillHang),"iBillHangDetailItemManager",iBillHangDetailItemManager);
ReflectionTestUtils.setField(AopTargetUtils.getTarget(genBillHang),"iDayBillSubtotalItemManage",iDayBillSubtotalItemManage);
ReflectionTestUtils.setField(AopTargetUtils.getTarget(genBillHang),"iAcctAccountManage",iAcctAccountManage);
ReflectionTestUtils.setField(AopTargetUtils.getTarget(genBillHang),"iAcctAccountRelationManage",iAcctAccountRelationManage);
ReflectionTestUtils.setField(AopTargetUtils.getTarget(genBillHang),"iUsersManage",iUsersManage);
ReflectionTestUtils.setField(AopTargetUtils.getTarget(genBillHang),"genConfig",genConfig);
}

设置上下文参数

1
2
3
4
5
6
7
8
9
10
11
//设置上下文
private void setContextParams() throws Exception{
Context.getContextParams().put("deal_mode",0);
Context.getContextParams().put("deal_type",1);
Context.getContextParams().put("dbi_type",14);
Context.getContextParams().put(Constants.Key.CITY_ID,14);
JobConfig jobConfig = new JobConfig();
jobConfig.setTotalTaskNum(2);
jobConfig.setTaskItemNum(0);
Context.getContextParams().put("jobConfig",jobConfig);
}

(三)期望、断言

1
2
3
4
5
// 设置返回对象
when(bgControl.getBGControlByCityId(anyInt())).thenReturn(null);
List list = bgWorkStorage.fetchData();
// 断言
Assert.assertNull(list);
1
2
3
bgWorkStorage.processData(workMQMessageBoList);
// 断言方法执行次数
verify(bgWorkManage, times(1)).updateWorkUsersBgFlagBatch(anyListOf(BGWorkUsersBo.class));

断言执行次数还有这些函数方法:never()atLeast()atLeastOnce()atMost()

timeout(100).times(2)代表100毫秒内被调用两次

(四)PowerMock

1
2
3
4
@PrepareForTest({BGWorkStorageTest.class,CollectionUtils.class, PropertiesUtil.class})
@PowerMockIgnore("javax.management.*")
public class BGWorkStorageTest {
}
1
2
3
4
@ObjectFactory
public ITestObjectFactory getObjectFactory() {
return new PowerMockObjectFactory();
}
1
2
3
4
5
6
7
8
9
// mock工具类
CollectionUtils collectionUtils = PowerMockito.mock(CollectionUtils.class);
// 替换被测试类中的变量
PowerMockito.whenNew(CollectionUtils.class).withAnyArguments().thenReturn(collectionUtils);
// mock静态方法
PowerMockito.mockStatic(CollectionUtils.class);
// 断言
PowerMockito.when(collectionUtils.isEmpty(anyList())).thenReturn(false);
PowerMockito.when(collectionUtils.isNotEmpty(anyList())).thenReturn(true);

(五)期望异常、模拟异常捕获

1
2
// 期望捕获异常:
@Test(expectedExceptions = com.newland.common.NLException.class)
1
2
// 模拟void函数
doNothing().when(spy).add(anyInt(), anyString());
1
2
3
4
// 模拟方法抛出异常
when(mock.someMethod()).thenThrow(new RuntimeException());
// 模拟void方法抛出异常
doThrow(new RuntimeException()).when(mock).someMethod();

补充:

when()匹配固定字符串的方式:

1
when(AcctFileProcessUtil.getNodeElement(anyString(), eq("MemProvCode"), eq("MemProvCode"))).thenReturn(null);

对于工具类没有返回值的情况,跳过执行:

1
2
PowerMockito.mockStatic(FileUtils.class);
PowerMockito.doNothing().when(FileUtils.class, "moveFile", (File) anyObject(), (File) anyObject());

对静态方法进行断言(前提:先使用PowerMock的注解)

1
2
PowerMockito.verifyStatic(times(1));
FileTool.writeFile(anyString(), anyString(), anyString(), anyListOf(String.class));