Console.ReadLine() を呼び出すメソッドの C# ユニット テスト 質問する

Console.ReadLine() を呼び出すメソッドの C# ユニット テスト 質問する

ScoreBoardゲームの上位 5 人のプレイヤーを保存する、というクラスのメンバー関数の単体テストを作成したいと思います。

問題は、私がテストを作成したメソッド ( SignInScoreBoard)がConsole.ReadLine()、ユーザーが自分の名前を入力できるように呼び出されることにあります。

public void SignInScoreBoard(int steps)
{
    if (topScored.Count < 5)
    {
        Console.Write(ASK_FOR_NAME_MESSAGE);
        string name = Console.ReadLine();
        KeyValuePair<string, int> pair = new KeyValuePair<string, int>(name, steps);
        topScored.Insert(topScored.Count, pair);
    }
    else
    {
        if (steps < topScored[4].Value)
        {
            topScored.RemoveAt(4);
            Console.Write(ASK_FOR_NAME_MESSAGE);
            string name = Console.ReadLine();
            topScored.Insert(4, new KeyValuePair<string, int>(name, steps));
        }
    }
}

10 人ほどのユーザーを挿入して、移動 (ステップ) 数が少ない 5 人が保存されているかどうかを確認する方法はありますか?

ベストアンサー1

Console.ReadLine を呼び出すコード行を別のオブジェクトにリファクタリングして、テストで独自の実装を使用してスタブ化できるようにする必要があります。

簡単な例として、次のようなクラスを作成できます。

public class ConsoleNameRetriever {
     public virtual string GetNextName()
     {
         return Console.ReadLine();
     }
}

次に、メソッド内で、代わりにこのクラスのインスタンスを取得するようにリファクタリングします。ただし、テスト時には、テスト実装でこれをオーバーライドできます。

public class TestNameRetriever : ConsoleNameRetriever {
     // This should give you the idea...
     private string[] names = new string[] { "Foo", "Foo2", ... };
     private int index = 0;
     public override string GetNextName()
     {
         return names[index++];
     }
}

テストするときは、実装をテスト実装と交換します。

確かに、個人的にはフレームワークを使用してこれを簡単にし、これらの実装の代わりにクリーンなインターフェースを使用しますが、上記の内容で正しいアイデアが伝われば幸いです...

おすすめ記事