2

TDD を使用して、C# (これは非常に初めてです) でコンソール アプリケーションを作成しようとしています。

文字列をキーとして、整数を値として含む辞書を反復処理し、それらを「キー:値」としてコンソールに出力しようとしています。私はさまざまなことを試しましたが、最終的にうまくいくものを見つけました:

    public void ShowContents ()
    {
        foreach (KeyValuePair<string, int> item in dictionary) {
            Console.WriteLine ("{0}: {1}", item.Key, item.Value);
        }
    }

私が抱えている問題は、これをテストする方法がわからないということです。私のテストは現時点では次のようになります。

[Test ()]
    public void CanShowContentsOfDictionary ()
    {
        dictionary.AddWord ("Hello");
        Assert.AreEqual ("Hello: 1", dictionary.ShowContents ());
    }

そして明らかに、何かがコンソールに出力されるのではなく、戻り値が期待されています。ここの他の場所で、Console.WriteLine が機能すると想定しているだけなので、ポイント テストがなかったことを読みました。代わりに、このメソッドで return を使用して、コンソールに書き込むだけの別のメソッドを記述できます (したがって、コンソールに書き込む必要はありません)。テストされます)。これに関する問題は、a) すべてのキーと値を返すメソッドの書き方がわかりません。b) 1 つのものを返すのではなく、さまざまな文字列を返します。

これについてどうすればよいかアドバイスはありますか?

4

2 に答える 2

3

によって出力された文字列全体を返す関数を作成できますShowContents。何かのようなもの:

public string GetContents()
{
    var sb = new StringBuilder();        
    foreach (KeyValuePair<string, int> item in dictionary) {
        sb.AppendLine(string.Format("{0}: {1}", item.Key, item.Value));
    }
    return sb.ToString();
}

次に、あなたShowContentsは次のとおりです。

Console.Write(GetContents());

GetContentsまた、 を使用せずに、期待どおりの結果を返すことをテストできますConsole.WriteLine

于 2015-03-29T22:34:42.883 に答える
1

あなたはすでに Blorgbeard の回答を受け入れていますが (この場合は明らかに完全に有効です)、質問に 2 セント追加したいと思います。

私が理解している限り、達成したい動作をテストする必要があります。事実上、質問と回答の間の変更により、テストは「このメソッドがすべての値をテキストリーダーに書き込むことをテストしたい」から「このメソッドがすべての値を連結して返すことをテストしたい」に変わります。書式設定ではなく、書き込み動作をテストしていません。

あなたの場合、この変更は問題ではありませんが、問題になる可能性があります。たとえば、大量のデータ セットをストリームに書き込みたいとします。データ全体をメモリにロードしないように、少しずつ書きたいと思うかもしれません。連結された文字列出力をテストする場合、テストに合格する可能性があります (完全なデータセットを使用しない場合、通常はテストでは使用しません)。本番環境ではデータが多すぎるために失敗します。

とにかく、メソッド a に渡すことで、書き込み動作をテストできますTextWriter。次に、テストで、TextWriter書き込まれたデータをチェックできるカスタムを渡すことができます。Console.Out本番コードでは、コンソールに書き込むために渡します。

public void ShowContents (TextWriter writer)
{
    foreach (KeyValuePair<string, int> item in dictionary) {
        writer.WriteLine ("{0}: {1}", item.Key, item.Value);
    }
}

// calling in production code
ShowContents(Console.Out);

を渡す代わりに、テスト用にConsole.SetOutを準備する場合は、このメソッドを使用することもできます。詳細については、Mark Seeman によるこの記事を参照してください。メソッドが静的テキストライターに書き込むのが好きではないので、コンソールの出力を変更するのはあまり好きではありません。関数が標準出力に書き込むことは何もわからないので、引数として TextWriter を渡すことを好みますConsoleTextWriter

于 2015-03-30T09:10:58.743 に答える