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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C#

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Q&A

解決済

5回答

6160閲覧

テストの書き方「いろは」の「ろ」を教えてください。

meshkit

総合スコア72

C#

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

0グッド

0クリップ

投稿2018/03/02 01:56

前提・実現したいこと

Visual Studio 2015 Proの内蔵MSTestでテストを書いています。
テストの書き方「いろは」の「ろ」を教えてください。

C#

1 public static bool IsNumber(string text) 2 { 3 if (text == null) return false; 4 else if (Regex.Match(text, "^[0-9]+$").Success) return true; 5 else return false; 6 }
があるとき、

C#

1 [TestMethod()] 2 public void IsNumberTest1() 3 { 4 string text = "012"; 5 Assert.AreEqual(true, Validation.IsNumber(text)); 6 } 7 8 [TestMethod()] 9 public void IsNumberTest2() 10 { 11 string text = "012a"; 12 Assert.AreEqual(false, Validation.IsNumber(text)); 13 } 14 15 [TestMethod()] 16 public void IsNumberTest3() 17 { 18 string text = "abc"; 19 Assert.AreEqual(false, Validation.IsNumber(text)); 20 }

をテストしました。
returnがあるときは、expectedに予定する値を入れればよいのですが、returnがvoidのとき、たとえば下記のMethodをTestするにはどういうテストコードを書けばよいですか?

static string BaseText = string.Empty; public static void SetText(string text) { BaseText = text; }

補足情報(FW/ツールのバージョンなど)

Visual Studio 2015 Pro

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

C#

1public static string GetText() { 2 return BaseText; 3}

を追加し、SetText("ほげほげ") ののち GetText() から "ほげほげ" が得られることをテストします。
こんなメソッド要らない/あってはダメなら #if FOR_TEST ~ #endif で囲んでおいて、テスト時のみこのコードを有効にすればいいス。

[追記] protected な例

C#

1using System; 2 3public class foo { 4 protected static string text; 5 public static void set(string str) { text = str; } 6} 7 8// ↑納品物 9 10// ↓テスト・コード 11 12public class for_test : foo { 13 public static string get() { return text; } 14} 15 16public class Program { 17 public static void Main() { 18 foo.set("hoge"); 19 Console.WriteLine(for_test.get()); 20 } 21}

投稿2018/03/02 02:05

編集2018/03/02 03:04
episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

meshkit

2018/03/02 02:41

ありがとうございます。なるぼど。 方法はわかりました。 メソッドはご推察のとおり、あってはだめと思います。 このメソッドじたいをテストプロジェクトに書くことはできますか? ``` [TestMethod()] public void voidTest1() { string original = "あいう"; Validation.SetText(original); string text = Validation.BaseText; Assert.AreEqual(text, original); } ``` とかでよいのでしょうか。
episteme

2018/03/02 02:47 編集

同様に #if ~ #endif を使って テストのときだけ BaseText を public にすればいいのでわ? リフレクション使ってprivateなメソッド/フィールドを参照することもできますが、「ろ」の範囲からは大きく外れますよね。
meshkit

2018/03/02 02:52

#if #endif でコード中に書くと、納品時に全部消すことになります。 それは避けたいです。...。
episteme

2018/03/02 02:54

納品時に全部消す? なんで?
episteme

2018/03/02 02:56

あとは...そうねぇ、BaseTextをprotectedにしておいて、テスト用にこしらえた導出クラスから読み出しますか。
meshkit

2018/03/02 03:00

なんでといわれても、客がいらないものを書くなと。
episteme

2018/03/02 03:08 編集

...ってお客様がおっしゃるですか。 んじゃ protected が次善の策かな(追記しといた # あ、リフレクション使った回答が上がってますヨ
meshkit

2018/03/02 04:01

ありがとうございます。お客様には勝てないです。
meshkit

2018/03/02 04:10

こまごまフォローありがとうございます!
guest

0

PrivateType を使ってください。

C#

1class Target 2{ 3 static string BaseText = string.Empty; 4 public static void SetText(string text) 5 { 6 BaseText = text; 7 } 8} 9 10[TestClass] 11public class UnitTest1 12{ 13 [TestMethod] 14 public void TestMethod1() 15 { 16 string testValue = "Foo"; 17 Target.SetText(testValue); 18 var target = new PrivateType(typeof(Target)); 19 var baseText = (string)target.GetStaticField("BaseText"); 20 Assert.AreEqual(testValue, baseText); 21 } 22}

投稿2018/03/02 03:20

Zuishin

総合スコア28660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

meshkit

2018/03/02 04:09

ありがとうございます。使いやすいコードです。活用します!
guest

0

ベストアンサー

PrivateType(staticで無い場合はPrivateObject)を使いましょう。

C#

1 [TestMethod()] 2 public void SetTextTest() 3 { 4 string original = "あいう"; 5 Validation.SetText(original); 6 7 var pt = new PrivateType(typeof(Validation)); 8 var text = pt.GetStaticField("BaseText") as string; 9 10 Assert.AreEqual(original, text); 11 } 12 }

投稿2018/03/02 02:59

HARQ

総合スコア181

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

meshkit

2018/03/02 04:09

ありがとうございます。わかりやすいコードです!
guest

0

SetTextを呼び出すことで、そのメソッドを持つクラスが外部に見える形で何らかの変化を起こすはずです。
その変化が期待通りであるかをテストします。

投稿2018/03/02 02:54

編集2018/03/02 03:17
ozwk

総合スコア13521

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2018/03/02 04:13

テストのためであれテスト対象に指一本触れてはならぬなら、リフレクションよりコチラを(僕は)推します。 何の変化も起こさないなら、そもそもそんなメソッド(and/or フィールド)は不要なのだから。
guest

0

SetText を呼び出した後に、BaseText の内容が書き換わっていることを確認すればよいだけでは?

投稿2018/03/02 02:03

koko_u

総合スコア936

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

meshkit

2018/03/02 02:42

ありがとうございます。なるぼど。 方法はわかりました。 いまいちコードにならず。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問