目录
问题来了
解决方法
1.不测试
2.改权限
3.进行内部测试
4.使用反射
具体实现
5 测试
补充
参考
在上一篇中:https://blog.csdn.net/qq_36110736/article/details/107774507,对Junit单元测试框架有了一定了解。
但紧接着问题就来了,对于一些 private 修饰的方法无法在外部直接调用,导致分支难以覆盖。
这里先来说一下网上对private修饰的方法进行单元测试的几种解决方法:
这是最消极的一种办法,毕竟大家都不会闲的没事,非要对一个private方法进行测试,一般来说都是有某种不可抗拒原因导致我们必须想办法进行测试(譬如说要求测试覆盖率达到一定标准,包含了复杂业务逻辑实现),否则的活没必要测试private方法。
将private方法变成protected或者package
这也是一种办法吧,但问题随之而来——当初我为啥要将方法的权限修饰为private访问权限?这种方法在我看来根本不可取。
在被测类中编写仅对测试有用的代码。
至于这种就更扯淡了,逻辑测试写在一起,大概只有初学者会这么搞吧,当你在某个项目组里这么做的时候你最好祈祷别被负责人打死。
此处我推荐使用反射来完成,这种才是真正解决问题的方式。
4.1 什么是反射
Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。
首先,在原有代码里添加一个private方法
public class Calculate {
public int add(int a,int b){
return a+b;
}
public int subtract(int a,int b){
return a-b;
}
public int multiply(int a,int b){
return a*b;
}
public int divide(int a,int b){
if (!isZero(b)){
return 0;
}else {
return a/b;
}
}
private boolean isZero(int num){
if (num != 0){
return false;
}else {
return true;
}
}
}
在测试代码里添加对应测试方法:
@Test
public void isZeroTest() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Class c = Calculate.class;
Calculate calculate = new Calculate();
Method method = c.getDeclaredMethod("isZero", int.class);// 声明调用哪个类的哪个方法
method.setAccessible(true);//允许处理私有方法
Assert.assertTrue((boolean)method.invoke(calculate,0));//断言+具体调用
Assert.assertFalse((boolean)method.invoke(calculate,1));
}
当然,由于测试类比较简单,所以也可以通过对 divide 方法进行分支覆盖的方式测试到isZero方法。
什么是断言?
编写代码时,我们总是会做出一些假设,断言就是用于在代码中捕捉这些假设。程序员相信在程序中的某个特定点该表达式值为真,可以在任何时候启用和禁用断言验证,因此可以在测试时启用断言而在部署时禁用断言。同样,程序投入运行后,最终用户在遇到问题时可以重新启用断言。
使用断言可以创建更稳定、品质更好且 不易于出错的代码。当需要在一个值为FALSE时中断当前操作的话,可以使用断言。单元测试必须使用断言(Junit/JunitX)
https://baike.baidu.com/item/%E6%96%AD%E8%A8%80/13021995
https://baike.baidu.com/item/JAVA%E5%8F%8D%E5%B0%84%E6%9C%BA%E5%88%B6
https://blog.csdn.net/caib1109/article/details/51338743