2

我想测试下面的两种方法,但因为它基于随机输出,所以我的首选方法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;

}
4

4 回答 4

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())Now,您可以对输入进行硬编码,例如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()). 在您的单元测试中,您可以对输入进行硬编码(使用类似于用于先前函数的方法)并根据您传递的参数断言您获得了预期的结果。

于 2013-05-13T02:56:09.390 回答
2

您发现的是您想要测试(断言)您的代码在给定某些输入的情况下是否正确运行,但是在编写代码时您无法轻松控制有问题的输入。恭喜!您已经发现了测试驱动开发的(其中之一)优点。

解决方案是以一种更容易测试您关心的属性的方式重新构建您的代码。

您关心该compRandomChoice功能的哪些属性?也许它会产生一个均匀分布在三个选项中的输出。为此,您可能会想象编写一个简短的测试来迭代许多调用compRandomChoice并进行一些简单的分析(和大数定律),以表明您在大约三分之一的时间内获得了每个选择。

功能怎么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);
}

看看编写可测试代码;它提供了很多关于如何成功地做你想做的事情的提示。

于 2013-05-13T03:02:39.293 回答
0

为了我的需要和可用的时间,我找到了 assertNotNull() 测试方法,并使用了它。

@Test
public void testGameWinner() {
    assertNotNull(testLogic.gameWinner());
于 2013-05-14T03:25:01.687 回答
0

我会将随机抽取到包私有方法中

double getRandomChoice() {
    return (Math.random() * 100 / 100);
}

这样在测试中我可以覆盖它

    MyClass mc = new MyClass() {
        @Override
        double getRandomChoice() {
            return 2.0;
        }
    };
于 2013-05-13T03:02:31.503 回答