java - 如何在 Java 中创建单元测试?
问题描述
我有一个 java 类,它接受一个数字数组和一个相应概率数组,并充当一个随机数生成器,它根据另一个定义的相应概率从数组中返回一个数字。如何编写最少但有效的单元测试集?
class RandomGen {
private int[] randomNums;
private float[] probabilities;
private float[] total_prob;
RandomGen(int[] randomNums, float[] probabilites) throws Exception {
if (this.set_arrays(randomNums, probabilites));
else {
throw new Exception("Invalid array format");
}
}
private boolean set_arrays(int[] randomNums, float[] probabilities) {
if (check_arrays(randomNums, probabilities)) {
this.randomNums = randomNums;
this.probabilities = probabilities;
this.total_prob = new float[this.probabilities.length];
total_prob[0] = probabilities[0];
for (int i = 1; i < probabilities.length; i++){
total_prob[i] = total_prob[i-1] + probabilities[i];
}
return true;
}
return false;
}
public int[] return_randomNums() {
return this.randomNums;
}
public float[] return_probabilites() {
return this.probabilities;
}
private boolean check_arrays(int[] randomNums, float[] probabilities) {
float total_prob = 0;
for (int i = 0; i < probabilities.length; i++) {
if (probabilities[i] < 0) return false;
total_prob += probabilities[i];
}
if (randomNums.length != probabilities.length || total_prob != 1) return false;
return true;
}
public int nextNum() {
float random = (float) Math.random();
if (random <= total_prob[0]) {
return randomNums[0];
}
for (int i=1; i < total_prob.length; i++) {
if (total_prob[i-1] < random && random <= total_prob[i]) return randomNums[i];
}
return 0;
}
}
解决方案
对于学习单元测试,这个类可能有点太复杂了。我们也可以在这里只触及表面,因为这不是你可以从几个例子中学到的。我敦促你买一本关于这个主题的书。
但是既然我们已经到了,让我们看看你的课。
您的类的公共接口由构造函数nextNum()
和两个 getter 组成(只返回字段的方法称为 getter,因为它们通常命名为getFieldName()
,例如getRandomNums()
)。
getter 不包含任何逻辑。因此,我会避免测试它们。
您的构造函数实际上做了很多工作。首先,它检查数组是否有效(长度相同且概率加起来为 1),然后存储数组并使用累积概率构建一个新数组。为了测试它,每个测试用例都会创建一个新的实例,RandomGen
其中包含不同的数组,这些数组构成不同的情况。显而易见的三种情况是:
- 概率加起来为一,但两个数组的长度不同
- 两个数组的长度相同,但概率数组元素的和不等于 1
- 两个数组的长度相同,概率加起来为 1
前两种情况是错误情况,预计会引发异常,最后一种情况是“阳光情况”,您可以在其中检查您的 getter 现在是否返回了两个数组。累积概率 ( total_prob
) 只能通过使用 来观察nextNum()
。
然后是nextNum()
方法。这已经有点高级了,因为你无法预测Math.random()
. 可能的解决方案是使用预定义的种子(正如 Victor Polo De Gyves Montero 建议的那样)或 wrap and injection Math.random()
。在您的情况下,我会跳过它并首先阅读一本书并获得一些单元测试经验。
推荐阅读
- python - SSL 请求失败 - Python OSX
- kubernetes - atching kube-system aws-node daemonset 失败,json 无效
- c# - 具有受保护设置器的可空属性,推断为朋友(内部)字段
- android - 所有产品风味都连接到一个构建变体
- google-analytics - Google Analytics - 搜索类别的高级搜索过滤器
- reactjs - 重定向链接到地图路线
- javascript - JavaScript new formData().append 不适用于上传的文件
- raku - 语法行为是否在 6.c 和 6.d 之间中断?
- pdf - 以 PDF 格式导出多个剑道网格
- javascript - 如何使用 Javascript 在移动 Safari 和所有其他浏览器上录制音频?