我想测试下面的两种方法,但因为它基于随机输出,我的首选assertEquals()
将无效。
我只想测试以确保方法产生某种输出。有任何想法吗?
新手程序员,谢谢你的帮助。 public void compRandomChoice() {
double choice = (Math.random() * 100 / 100);
if (choice > 0 && choice <= 0.34) {
computer.setChoice(HandThrow.ROCK);
} else if (choice > 0.34 && choice <= 0.67) {
computer.setChoice(HandThrow.PAPER);
} else {
computer.setChoice(HandThrow.SCISSORS);
}
}
public String gameWinner() {
String gameResult;
if (human.getChoice() == computer.getChoice()) {
gameResult = "ITS A TIE!";
} else if (human.getChoice() == HandThrow.ROCK
&& computer.getChoice() == HandThrow.SCISSORS
|| human.getChoice() == HandThrow.PAPER
&& computer.getChoice() == HandThrow.ROCK
|| human.getChoice() == HandThrow.SCISSORS
&& computer.getChoice() == HandThrow.PAPER) {
gameResult = "CONGRATS, YOU WIN!";
} else {
gameResult = "COMPUTER WINS!";
}
return gameResult;
}
答案 0 :(得分:3)
我建议更改compRandomChoice()
功能如下
public void compRandomChoice(double rand_no) {
double choice = (rand_no * 100 / 100);
if (choice > 0 && choice <= 0.34) {
computer.setChoice(HandThrow.ROCK);
} else if (choice > 0.34 && choice <= 0.67) {
computer.setChoice(HandThrow.PAPER);
} else {
computer.setChoice(HandThrow.SCISSORS);
}
}
然后在您的计划中,您可以将其称为compRandomChoice(Math.random())
现在在您的单元测试中,
你可以硬编码输入,例如compRandomChoice(0.5)
并断言结果符合预期。
同样,将public String gameWinner()
更改为public String gameWinner(String human_choice, String computer_choice)
public String gameWinner(String human_choice, String computer_choice) {
String gameResult;
if (human_choice == computer_choice) {
gameResult = "ITS A TIE!";
.......
在您的代码中,您可以将该函数称为gameWinner(human.getChoice(), computer.getChoice())
。在单元测试中,您可以对输入进行硬编码(使用类似于以前函数的方法),并根据您传递的参数断言您获得预期结果。
答案 1 :(得分:2)
您要发现的是,您希望在给定某些输入的情况下测试(断言)您的代码行为正确,但在编写代码时无法轻松控制相关输入。恭喜!您已经发现了(测试驱动开发的优点之一)。
解决方案是以一种更容易测试您关注的属性的方式重新构建代码。
您关心compRandomChoice
功能的属性是什么?也许它产生的输出均匀分布在三个选项中。要做到这一点,你可以想象编写一个简短的测试,迭代许多对compRandomChoice
的调用,并进行一些简单的分析(和大数定律),以表明你在三分之一的时间内得到了每个选择。 / p>
gameWinner
功能怎么样?在那里你想尝试不同的输入组合,并确认确定正确的赢家。算法的输入是计算机和人类做出的选择。因此,要测试它,您必须能够制造人类和计算机选择并将它们提供给算法。这通常是通过使用依赖注入来完成的......它提供了算法在构造函数中所依赖的对象,或者作为参数而不是对它们进行硬编码。
例如,最简单的方法是将选项传递给gameWinner
函数并让它返回获胜者(例如,作为枚举):
enum Result { PLAYER1, PLAYER2, TIE }
/**
* Determine the game winner.
* @param player1_choice
* @param player2_choice
* @return PLAYER1 .
*/
public Result gameWinner(HandThrow player1_choice, HandThrow player2_choice) {
if (player1_choice.equals(player2_choice)) { return TIE }
...
}
然后测试很容易写:
@Test
public void paperBeatsRock() {
assertEquals(gameWinner(HandThrow.ROCK, HandThrow.PAPER), PLAYER2);
}
看看Writing Testable Code;它提供了很多关于如何成功完成工作的提示。
答案 2 :(得分:0)
我会提取随机进入包私有方法
double getRandomChoice() {
return (Math.random() * 100 / 100);
}
所以在测试中我可以覆盖它
MyClass mc = new MyClass() {
@Override
double getRandomChoice() {
return 2.0;
}
};
答案 3 :(得分:0)
根据我的需要和时间,我找到了assertNotNull()测试方法,并使用了它。
@Test
public void testGameWinner() {
assertNotNull(testLogic.gameWinner());