2017-10-20 8 views
-1

まあ、特定のイベントを含むクラスをテストするためのテストスイートを作成しようとしました。基本的にはメソッドを呼び出し、そのメソッドにイベント、テストコードとイベントが実行されるオブジェクト、そしてイベントが発生する予想される時間を与えたいと思います。一般的なイベントテストメソッド、コードの重複を防ぐ

私の最初の反復は、次のとおりです。

protected void EventFireTest<T>(EventHandler theEvent, T g, TestAction<T> action) where T: class{ 
     var invokeChangedCount = 0; 

     theEvent += (sender, e) => { ++invokeChangedCount; };    

     foreach (var actionPair in action.AllActions) { 
      invokeChangedCount = 0; 
      var num = actionPair.Item2; 
      var actualAction = actionPair.Item1; 
      actualAction(g); 

      Assert.That(actual: invokeChangedCount, expression: Is.EqualTo(expected: num)); 

     } 
    } 

それは次のように呼ばれることになります。

EventFireTest(obj.PropertyChanged、OBJ、アクション)。

アクションには、アクションペアと、実行されるアクションの視覚的手がかりのようなメタデータが含まれています。

しかし、この関数にイベントを渡そうとしたとき、問題は「イベントは+ =と - =のlhsだけです」という問題がありました。それが唯一の事だが、私は最終的にイベントでやった。

私はこの問題を回避するために、すでに不必要なコードの重複を直接導入し、内部の詳細を外側のテストメソッドに流し込むように、より肥大化したアプローチに行きました。実行するためにEventFireTestメソッドのためのラムダを提供することによって。

protected void EventFireTest<T>(Action<int> EventSetupAction, T g, TestAction<T> action) where T: class{ 
     var invokeChangedCount = 0; 

     EventSetupAction(invokeChangedCount); 

     foreach (var actionPair in action.AllActions) { 
      invokeChangedCount = 0; 
      var num = actionPair.Item2; 
      var actualAction = actionPair.Item1; 
      actualAction(g); 

      Assert.That(actual: invokeChangedCount, expression: Is.EqualTo(expected: num)); 

     } 
    } 

今のコードのように呼ばれることになります。

 Action<int> setup = n => obj.PropertyChanged += (sender, e) => { 
      ++n; 
     }; 
     EventFireTest(setup, obj, action); 

私はuglynessが(突然私はイベントの実行をはカウントしどのように行われるかを気にする必要があります)すでにかなり見えていると思います。しかし、上記のコードが重要なことは機能しません。

EventFireTestの変数を「変更」する代わりに、lambdaは変数のローカルコピーを作成し、それを更新します。だから私は参照によって整数を渡す必要がありますが、これはやはり複雑な方法では不可能です。

これらの問題が組み合わさって、私は現在、これを解決する正しい方法がないと信じています。ほとんどの場合、より簡単な方法がありますか?

答えて

-1

デリゲートに整数を与えてインクリメントするのではなく、デリゲートにイベントハンドラを提供させ、デリゲートの本体にそのイベントハンドラをイベントに追加させます。

Action<EventHandler> setup = handler => obj.PropertyChanged += handler; 
EventFireTest(setup, obj, action); 

あなたが今ちょうどあなたがあなたの元のリビジョンに書いたハンドラを取り、そのアクションにパラメータとして渡す必要がある試験方法の場合:これは、呼び出し元になります。

問題を回避するもう1つの方法は、Tを、一部のインターフェイスを実装するタイプに制限することです。インターフェイスでは、購読する必要のあるイベントを定義します。これは、このテストのすべての呼び出し元が任意のイベントではなく特定のタイプのイベントを論理的にテストしている場合にのみ適切です。あなたのコードは後者のように見えるので、あなたの状況に適しているとは思われません。

+0

これはエラーを発生させます: '暗黙のうちに 'System.EventHandler'型を 'System.ComponentModel.PropertyChangedEventHandler'に変換できません。今では、「カスタムイベント」と「組み込みイベント」で実際に動作するようにしたいと考えています。だから「T」を拘束することは、私が実際にやりたくないことです。 – paul23

+0

@ paul23特定の種類の代理人ではなく、*あらゆる種類のイベントの問題を解決したい場合、問題は[この問題](https://stackoverflow.com/questions/12865848)と同じです。/general-purpose-fromevent-method)は、あなたがしたい場所ではありませんが、もしそれがあなたがしなければならないことなら、あなたがしなければならないことです。 – Servy

+0

問題は、いくつかの異なるタイプのオブジェクトに対して、「PropertyChanged」、「PropertyChanging」、「DataChanged」、「DataChanging」、およびすべての「テストする必要がある」コレクションベースのイベントです。 - これは実際にコードの複製が「標準的な」方法ですか? (リンクされた答えは現時点で私のスキルセットにとっては "難しい"もので、テストツールとしては適していません)。 – paul23

関連する問題