質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.35%

  • C#

    4756questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

単体テストにおけるメンバ変数の扱い方

解決済

回答 1

投稿 2017/12/01 10:34 ・編集 2017/12/01 10:37

  • 評価
  • クリップ 0
  • VIEW 239

---t---

score 25

表題の件で質問させてください
現在単体テストの学習を行っているのですが
テスト対象の引数なしのメソッド内にメンバ変数を使用している場合にテストメソッドからどう渡せばよいでしょうか?

初歩的な質問で申し訳ありませんがアドバイスよろしくお願いいたします

テストメソッド

 [TestClass()]
    public class comboboxdataTests
    {
        comboboxdata _comboboxdata = new comboboxdata();

        [TestMethod()]
        public void combodataGetTest()
        {
      //関数は呼び出せるがメンバ変数が渡せない
            _comboboxdata.combodataGet();
       

        }
    }
public class comboboxdata
    {


        public DataTable Combotb { get; set; }
        public Dictionary<string, int> Dic3 { get; set; }


        NpgsqlCommand command;
        Dictionary<string, int> dic3 = new Dictionary<string, int>();


        public void combodataGet()
        {
            var connString = "Server=test;Port=5432;User Id=test;Password=test;Database=test;";
            using (var conn = new NpgsqlConnection(connString))
            {
                conn.Open();

                //列データ取得SQL
                command = new NpgsqlCommand("select line_name,line_num from kado_sys.line_mstr ", conn);

                //変数commandのSQLの内容をExecuteReader()で読み取り変数dataReaderに代入
                var dataReader = command.ExecuteReader();

                DataTable combotb = new DataTable();

                combotb.Columns.Add("line_name");

                //DataTableのインスタンスにsublinerow1という行を定義
                var sublinerow1 = combotb.NewRow();

                //tbのname列のrow1(name)行のセルに全サブラインを定義
                sublinerow1["line_name"] = "全サブライン";

                //tbのname列のrow1(name)行のセルに全サブラインを挿入
                combotb.Rows.Add(sublinerow1);

                while (dataReader.Read())
                {
                    //DataTableのインスタンスにsublinerow2という行を定義(1:0)
                    var sublinerow2 = combotb.NewRow();
                    {
                        //dic3:ST名をキーに指定([0]はST名,[1]はST番号)、ST番号をバリューに指定               
                        dic3[dataReader[0].ToString()] = Convert.ToInt32(dataReader[1]);

                        //dic3[dataReader[0].ToString()] = combotb.Rows.Count;
                        sublinerow2["line_name"] = dataReader["line_name"];
                        // dataReader["line_name"]はDBからとってくるデータの為名前は欲しい列と一致させる
                    }
                    combotb.Rows.Add(sublinerow2);
                }

                dic3["全サブライン"] = -10;
                Combotb = combotb;
                Dic3 = dic3;


            }
        }
    }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

ご質問の意図が「privateなフィールド(メンバー変数)を参照する引数無しのメソッドを単体テストするにはどうしたらいいのか」と言うことで回答させていただきます。

privateなフィールド(メンバー変数)を単体テスト側から操作したい場合はPrivateObjectクラス(Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject)を使うことでセットできます。
これで(単体テストの為に)publicなフィールドやプロパティを用意しなくてもよくなります。若干面倒くさいコードになりますが。

teratailの過去の質問回答ですが、こちらが参考になると思います。
リフレクションでプライベートメンバを取得したい

せっかくですので、質問者様の単体テストにこれを使用してみたコードを例示します。少し冗長にしていますので、ご利用の際は適当に取捨選択してください。

[TestMethod()]
public void combodataGetTest2()
{
    //関数は呼び出せるがメンバ変数が渡せない
    _comboboxdata.combodataGet();

    var obj = new PrivateObject(_comboboxdata);

    // comboboxdataクラスのprivateフィールド dic3 にアクセスする。

    var field = obj.GetField("dic3");
    if (field is Dictionary<string, int>)
    {
        var dic = (Dictionary<string, int>)field;
        // 値をセットする。
        dic.Add("Key1", 1);
        dic.Add("Key2", 2);
        dic.Add("Key3", 3);
    }

    // dic3の内容を出力してみる(※後述)
    _comboboxdata.DumpPrivateDic3();
}


この例の確認用に、comboboxdataクラスに以下のpublicメソッドを追加してます。

public void DumpPrivateDic3()
{
    Debug.WriteLine("dic3: number of items={0}", dic3.Count);
    foreach (var k in dic3.Keys)
    {
        Debug.WriteLine(" -- k={0}, v={1}", k, dic3[k]);
    }
}

テストメソッドcombodataGetTest2を実行すると、デバッグ端末に以下のように出力します。privateフィールドのdic3へ外からセットした値がダンプできていることが分かります。

dic3: number of items=3
 -- k=Key1, v=1
 -- k=Key2, v=2
 -- k=Key3, v=3

投稿 2017/12/01 13:58

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.35%

関連した質問

同じタグがついた質問を見る

  • C#

    4756questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。