teratail header banner
teratail header banner
質問するログイン新規登録

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

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

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

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

Visual Studio

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

Q&A

解決済

1回答

1993閲覧

ジェネリック型のStaticクラスのprivateメソッドの単体テストを実施したい

nabe7887

総合スコア1

C#

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

Visual Studio

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

0グッド

1クリップ

投稿2022/11/07 22:58

0

1

前提・実現したいこと

ジェネリック型のStaticクラスのprivateメソッドの単体テストを実施したいです。
ジェネリック型でないStaticクラスはInvokeStaticメソッドで呼び出せたのですが、ジェネリック型のStaticクラスの呼び出し方は調べても分かりませんでした。

InvokeStatic(string name, Type[] parameterTypes, object[] args, Type[] typeArguments)で呼び出すのかなと思ったのですが、引数に何を入れればよいか分かりませんでした。
ジェネリック型の型引数としては下記テスト対象ソースコード内のTestenumを想定しています。

ご教授いただければ幸いです。
よろしくお願いいたします。

発生している問題・エラーメッセージ

System.MissingMethodException:メソッド 'Project1.Class.Num' が見つかりません

テスト対象ソースコード

c#

1 public class Class 2 { 3 public enum Testenum 4 { 5 Defult = 0, 6 Normal = 1 7 } 8 9 private static T Num<T>(T a) 10 { 11 return a; 12 } 13 }

呼び出し側ソースコード

c#

1 [TestMethod()] 2 public void NumTest() 3 { 4 PrivateType privateType = new PrivateType(typeof(Class)); 5 var actual = privateType.InvokeStatic("Num", new Type[] { typeof(Testenum) }, Testenum.Defult, new Type[] { typeof(Testenum) }); 6 }

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

Visual Studio 2019 Community
C#

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

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

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

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

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

Zuishin

2022/11/08 02:14

https://learn.microsoft.com/ja-jp/dotnet/api/microsoft.visualstudio.testtools.unittesting.privatetype.invokestatic?view=visualstudiosdk-2022#microsoft-visualstudio-testtools-unittesting-privatetype-invokestatic(system-string-system-type()-system-object()-system-type()) typeArguments が型引数です。 しかし通常プライベートメソッドのテストは不要です。テストしなければならないとすれば、設計を見直してクラスを分割する方が良いケースが多いです。
nabe7887

2022/11/08 07:56

ご返信と参考サイトをありがとうございます。 初めて単体テストに取り組むので、そのような智賢は大変勉強になります。
Zuishin

2022/11/08 08:44

本当ですか? どこまで知っていてどこまで確かめたかをちゃんと書かないと変な回答がつきますよ。 Visual Studio 2022 で InvokeMethod を選択して F12 を押すと、それを定義しているソースコードが表示されます。 最終的に type.GetMethod でメソッドを取得していますが、同じ方法で取得しようとパラメータを色々試してみたところ、どうもこれではジェネリックメソッドは取得できないようです。 つまり、「InvokeStatic ではできないだろう」という結論になります。 ソースコードを見るとジェネリックにも対応しているような書き方をしているので、バグかもしれません。 そこで、InvokeStatic ではなく、自前でメソッドを検索することで、Num() を呼び出すことに成功しました。 その方法であれば回答できますが、InvokeStatic を用いる方法、また GetMethod の InvokeStatic 内で使用されているオーバーロードを使ってメソッドを検索する方法はみつけることができませんでした。 逆に、その GetMethod を使ってジェネリックメソッドは検索できないという情報なら、非公式ですがいくつか見当たりました。
nabe7887

2022/11/08 10:27

非常に丁寧な回答を頂きありがとうございます。 InvokeStaticを用いた方法では無理なのですね。 私は引数に色々入れてみたりして、見当違いな方法を取り組んでいました。 F12 キーで定義へ移動することも初めて知りました。 ただ漠然と単体テストを実施するだけでなく、ショートカットキー等も併せて少しずつ覚えていきたい と思います。 お手数をおかけして恐縮ですが、自前でメソッドを検索する方法をご教示願えませんでしょうか。
guest

回答1

0

ベストアンサー

以下のコードでテストできます。

csharp

1var method = typeof(Class) 2 .GetMethods(BindingFlags.NonPublic | BindingFlags.Static) 3 .OfType<MethodInfo>() 4 .First(a => a.Name == "Num") 5 .MakeGenericMethod(typeof(Testenum)); 6 7Assert.AreEqual(Testenum.Defult, method.Invoke(null, new object[] { Testenum.Defult })); 8Assert.AreEqual(Testenum.Normal, method.Invoke(null, new object[] { Testenum.Normal }));

投稿2022/11/08 10:31

Zuishin

総合スコア28675

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

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

nabe7887

2022/11/08 11:09

こちらのコードで単体テストを実施することができました。 非常に助かりました。誠にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問