1.对于try——catch的测试案例
示例代码:
try {
if (nodeSelf() == null) {
log.info("node not init");
return;
}
} catch (Exception e) {
log.info("flyway not running");
return;
}
对应单元测试:
对于这段代码,我们需要根据它的功能来编写单元测试。这个代码段看起来是用来检查某个节点是否初始化,并且当发生异常时记录日志并返回。
首先,我们需要确定
nodeSelf()
方法的返回值,两种思考,如果它返回null
,那么代码会记录一条信息并返回。如果它抛出异常,代码会捕获这个异常,记录一条信息并返回。
//1.造成第一种状况返回null,不抛出异常
Mockito.when(nodeManager.queryNodeSelfDTO()).thenReturn(nodeSelfDTO);
//2.造成第二种状况,出现异常方法
Mockito.when(nodeManager.queryNodeSelfDTO()).thenThrow(new RuntimeException("flyway not running"));
try {
nodeManager.queryNodeSelfDTO();
fail("can not reach here!");
} catch (Exception e) {
assertFalse("抛出异常,未获取到值!",e instanceof Exception);//是否抛出异常
}
2.对于静态方法的测试
示例代码:
if (StringUtils.isNotBlank(nodeId)) {
remoteNodeInfo.setNodeId(nodeId);
}
对应单元测试:
//静态方法打桩,测试返回true
MockedStatic<StringUtils> StringUtilsMockedStatic= Mockito.mockStatic(StringUtils.class);
StringUtilsMockedStatic.when(()-> StringUtils.isNotBlank(nodeId)).thenReturn(true);
3.有(无)返回值的方法打桩
无返回值的案例:
nodeConfigProvider.deleteCached();
对应单元测试:
@Mock
private NodeConfigProvider nodeConfigProvider;
Mockito.doNothing().when(nodeConfigProvider).deleteCached();
有返回值的案例:
nodeConfigProvider.getCached()
对应单元测试:
@Mock
private NodeConfigProvider nodeConfigProvider;
Mockito.when(nodeConfigProvider.getCached()).thenReturn(nodeConfig);
4.私有方法测试
示例代码:
/* 校验节点操作是否合法
*/
private void validateNodeStatus(NodeDO partnerNodeDO, NodeAuthStatusEnum terminated) {
}
对应单元测试:
1.第一种可以采用将原代码的私有属性修改成公共属性
2.在不修改原代码的情况下,我建议采用反射的方式对代码进行私有属性的测试
@Test
public void validateNodeStatusTest() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
NodeWebServiceImpl nodeWebService = new NodeWebServiceImpl();
Method validateNodeStatus = nodeWebService.getClass().getDeclaredMethod("validateNodeStatus");
validateNodeStatus.setAccessible(true);
assertEquals("Private method is called.", validateNodeStatus.invoke(nodeWebService));
}
5.断言测试传入参数
被测试代码:
传入参数有两个,我们分别将传入参数进行捕获断言测试
//更新商户信息
nodeManager.updateMerchant(node, nodeSelfDO);
对应单元测试:
注意这里有两个参数,所以我们进行了两次的参数捕获的类的构造,最终将参数传入函数中去
ArgumentCaptor<NodeDO> argument1 = ArgumentCaptor.forClass(NodeDO.class);
ArgumentCaptor<NodeSelfDO> argument2 = ArgumentCaptor.forClass(NodeSelfDO.class);
verify(nodeManager).updateMerchant(argument1.capture(),argument2.capture());
assertEquals("mockArgument2", argument2.getValue());
assertEquals("mockArgument1", argument1.getValue());