如何对Java中的任何输出进行JUnit测试

时间:2013-05-13 02:48:14

标签: java unit-testing junit

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

答案 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());