2012-01-06 7 views
1

私が作成しているWindowsフォームアプリケーションに問題があります。アプリケーションは統合テストアプリケーションであると考えられます。基本的には、私のクラスの一つで多くのWebサービスを利用するメソッドをテストすることになっています。私はリフレクション経由でテストしたいクラスのメソッドをロードしていますが、このようなので、やっている:これは、Webサービスと場所をテストするために作成されている、そのクラスのメソッドのリストを返すリストボックスで選択したメソッドを呼び出す

private List<string> GetMethods(Type type) 
{ 
    return (from method in type.GetMethods() where method.IsPublic && 
     method.ReturnType == typeof(void) select method.Name).ToList(); 
} 

ユーザーが好きなだけ多くのメソッドを選択できるListBoxに配置します。私の混乱はここに来る。私がしたいのは、ユーザーが選択したメソッドを取得し、対応するメソッドXを実行することです(フォームにメソッドを実行する回数を入力するためのテキストボックスがあります)。私はリフレクションを通して得たメソッドの名前に基づいてこれらのメソッドを実行する方法を理解できません。私はこのような何かを試してみたが、私はそれが適切ではないことを知っている:これもコンパイルされません

private void RunMethods(Type type) 
{ 
    var tester = new ClassToTest(); 
    foreach(var item in lstMethodList.SelectedItems) 
    { 
     foreach(var method in type.GetMethods()) 
     { 
      if(String.Equals(item.ToString(), method.Name)) 
      { 
       ThreadStart ts = new ThreadStart(method.Name); 
       Thread thread1 = new Thread(ts); 
       thread1.Start(); 
      } 
     } 
    } 
} 

、ThreadStartはパラメータとしてメソッド名を必要とします。これが可能な方法はありますか?論理的に間違っているかもしれませんが、実行する必要のあるメソッドごとにスレッドを作成して、そのメソッドを何度も実行したいと考えています。これは、いくつかの負荷テストと一緒に統合テストを行い、Webサービスが何を処理できるかを確認する方法と考えられています。

+0

グーグルが助けになりませんでしたか? http://www.codeproject.com/KB/cs/C__Reflection_Tutorial.aspx – Zenwalker

+0

静的メソッドまたはインスタンスメソッドと呼ばれるメソッドはありますか? –

+0

これは私が呼び出そうとしているすべてのインスタンスメソッドです。メソッドを取得しているクラスは、テストするクラスを_テストするクラスなので、私は間違っていると思うようになり始めています。おそらく、私はメソッドを取得する必要があります。クラス自体はテストする必要があります。 – Zajn

答えて

0

Activatorを使用してクラスのインスタンスを作成できます。

次に、Invokeを使用してそのメソッドの1つを呼び出すことができます。このような

何か作業をする必要があります:

private void RunMethods(Type type) 
{ 
    foreach(var item in lstMethodList.SelectedItems) 
    { 
     foreach(var method in type.GetMethods()) 
     { 
      if(String.Equals(item.ToString(), method.Name)) 
      { 
       MethodInfo capturedMethod = method; 
       var t = new Thread(() => ThreadMain(type, capturedMethod)); 
       t.Start(); 
      } 
     } 
    } 
} 

static void ThreadMain(Type type, MethodInfo mi) 
{ 
    object o = Activator.CreateInstance(type); 

    object[] parameters = new object[] { }; 

    mi.Invoke(o, parameters); 
} 

を私がテストされているクラスはパラメータなしのコンストラクタを持っていると仮定しました。

+0

はい、テスト対象のクラスには、パラメータのないコンストラクタがあります。私のクラスは、私がそれを考えると少し複雑です。私はテストしたいクラスをテストするための単体テストを持つクラスを持っています...そして、このWindowsフォームからそのユニットテストクラスを呼び出そうとしています。私は最終製品でそれをしたくありませんが、Windowsフォームから実際にメソッドを呼び出せることをテストするために今行っています。私はユニットテストではなく統合テストを持つ別のクラスが必要かもしれないと思います。 – Zajn

+0

私は今これを試してみました。それは正しい軌道に乗っていると思います。ありがとうニコラス! – Zajn

1

あなたが望む方法を得るために、このようなものを使用することができます:あなたは(メソッドが静的である場合にのみ動作します)あなたが書くでしょう、別のスレッドでメソッドを呼び出したい場合は、

private List<MethodInfo> GetMethods(Type type) 
{ 
     return (from method in type.GetMethods() 
       where method.IsPublic && 
        method.ReturnType == typeof(void) 
       select method).ToList(); 
} 

を:

foreach(MethodInfo mi in GetMethods(SomeType) { 
    MethodInfo tempMi = mi; 
    Action myAction = (Action) Delegate.CreateDelegate(typeof(Action), tempMi); 
    ThreadStart ts = new ThreadStart(myAction); 
    Thread thread1 = new Thread(ts); 
    thread1.Start(); 
} 

それとも、書きます(メソッドは、パラメータを取ることが継承されたメソッドの用心、厳密にはパラメータを持っていない場合のみ!):

foreach (MethodInfo mi in GetMethods(type)) 
{ 
    MethodInfo tempMi = mi; //modified closure 
    object o = Activator.CreateInstance(type); 
    Action myAction = delegate() { tempMi.Invoke(o, null); }; 
    ThreadStart ts = new ThreadStart(myAction); 
    Thread thread1 = new Thread(ts); 
    thread1.Start(); 
} 

メソッドがパラメータを受け取る場合は、nullInvokeメソッドの現在のMethodInfo)の代わりに、オブジェクトの配列(object [] { ... })を渡す必要があります。もちろん、配列内のオブジェクトを修正します。

スレッドのリストを取得し、リスト内の各MethodInfoに対して新しいスレッドを追加すると、後でそのスレッドを制御することができます(後で停止したい場合など)。 HashMapも良い選択です。キーはMethodInfoまたはActionであり、値は関連付けられたThreadです。

+0

これは有望ですが、私はそのように自分のコードを変更し、実行時に "ターゲットメソッドへのエラーバインディング"エラーが発生します。これは自分のロジックではなく他の場所での私のコードのエラーかもしれません。 – Zajn

+1

メソッドは静的であると仮定しました。 –

+0

テストされているメソッドには引数がありますが、アクションタイプを使用しているのでこのコードを使用しないでください。編集@NicholasButlerが正しいです。 – Max

0

MethodInfosとメソッド名を保持するプライベート辞書を実装できます。

private Dictionary<string, MethodInfo> methodList; 
     private List<string> GetMethods(Type type) 
     { 
      methodList = new Dictionary<string, MethodInfo>(); 

      type.GetMethods().Where(m=>m.IsPublic && m.ReturnType.Equals(typeof(void))).ToList().ForEach(m=> 
       methodList.Add(m.Name,m) 
       ); 

      return methodList.Keys.Select(k => k).ToList(); 
     } 

ドロップダウンの選択時に、そのメソッドを辞書で見つけて実行することができます。

関連する問題