我编写了一个方法来重排String
数组
因此,任务是为名称列表的给定字符串数组实现WhiteElephant概念。应生成与原始元素匹配的赋值。
我编写了一个方法来选择一个随机数并使用一个映射来存储这些值,以便每个值都有不同的索引。但这只打印出5个值。我现在很困惑。
public static String[] generateAssignments(final String[] participants) {
Random r = new Random();
int size = participants.length;
HashMap val = new HashMap();
int change = 0;
String[] assignments = new String[6];
System.out.println("Using arrays");
for(int i=0; i<size;i++){
for(int j =0; j<size; j++){
change = r.nextInt(size);
if(val.containsValue(change) || change==i){
continue;
}
else val.put(i, change);
assignments[i] = participants[change];
System.out.println(assignments[i]);
break;
}
}
return assignments;
}
感谢您的投入。 谢谢, 幸运
答案 0 :(得分:2)
如果你的shuffle方法是随机的(或伪随机的),那么单元测试几乎是不可能的,因为输出是非确定性的。如果您允许播种随机数生成器,那么您可以确保在给定相同种子的情况下输出是一致的,但这并不表示随机性。
您还可以多次运行随机播放方法,并检查每张卡片在每个索引处显示的是相等的次数。在足够多的模拟中,这应该有助于说明随机性。
答案 1 :(得分:1)
仅供参考 - 您的shuffle()
代码和测试都存在一些逻辑错误。我不会在这里谈到这些;希望有一个好的测试可以让你找出问题!
Random
数据编写测试很难。最好的选择是将Random
的实例传递到您的shuffle()
方法,或者它包含class
。然后在测试用法中,您可以传入已使用已知值播种的Random
实例。鉴于Random
代码每次都会表现相同并且您控制输入数组,您的测试将是确定性的;您可以放心地assert
对已排序集合中的每个对象。
这种方法的唯一缺点是,您将无法通过测试来阻止您重新编写shuffle()
方法,只需将元素每次重新排序到此指定内容中订购。但这可能过度思考了;通常我们可以相信我们未来的自我。
另一种方法是假设在随机世界中,给定足够的时间,将实现每种数据的可能性。
我在测试6面骰子的roll()
方法时使用了这种方法。我需要确保从1-6获得所有值是可能的。我不想让方法签名或Die
构造函数复杂化以接受Random
的实例。我也对使用已知种子的测试没有信心,并且总是断言3
(即)。
相反,我假设给定足够的卷,1-6中的所有值最终都会被滚动。我写了一个无限调用roll
的测试,直到返回1-6的所有值。然后我在测试中添加了timeout
,如果上述条件没有得到满足,它将在1秒后失败。
@Test(timeout = 1000)
public void roll_shouldEventuallyReturnAllNumbersBetweenOneAndSixInclusively() {
Die die = new Die();
Set<Integer> rolledValues = new HashSet<Integer>();
int totalOfUniqueRolls = 0;
while (rolledValues.size() < Die.NUM_SIDES) {
if (rolledValues.add(die.roll())) {
totalOfUniqueRolls += die.getFaceValue();
}
}
assertEquals(summation(1, Die.NUM_SIDES), totalOfUniqueRolls);
}
最糟糕的情况是它在1秒后失败(尚未发生),但它通常会在大约20毫秒内通过。
答案 2 :(得分:1)
测试必须是可重复的:如果它取决于随机的东西,它就无用了。
我建议您使用 mocking ,因此CUT(测试中的代码)不使用在生产中实例化的真实Random
类,而是使用可预测的不同类编写的行为,使您有可能对两个或三个项目做出一些重要的断言。
答案 3 :(得分:0)
您的shuffle()
方法似乎总会返回相同的结果。因此,如果测试中包含许多元素的输入测试数组,只需指定您期望的确切输出数组。
看起来你正在尝试编写一个非常通用的测试。相反,您的测试应该非常具体:给定一个特定的输入A,那么您期望一个特定的输出B.