2

以下の 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())、単体テストでそれを呼び出すことができます。たとえば、入力をハードコーディングし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

あなたが発見しているのは、特定の入力が与えられたときにコードが正しく動作することをテスト (アサート) したいが、コードが書かれているときに問題の入力を簡単に制御できないということです。おめでとう!テスト駆動開発の長所 (の 1 つ) を発見しました。

解決策は、関心のあるプロパティを簡単にテストできるようにコードを再構築することです。

関数のどのプロパティを気にしcompRandomChoiceますか? おそらく、3 つの選択肢に均等に分散された出力が生成されます。そのためには、 を何度も呼び出して反復し、compRandomChoiceいくつかの簡単な分析 (および大数の法則) を行って、各選択肢が約 3 分の 1 の確率で得られることを示す短いテストを作成することを想像するかもしれません。

機能的にはどう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

ランダム取得をパッケージのプライベート メソッドに抽出します

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

テストでそれをオーバーライドできるように

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

私のニーズと利用可能な時間のために、 assertNotNull() テストメソッドを見つけて使用しました。

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