2017-06-07 7 views
0

Execute()メソッドを同時に呼び出すことができる一連のコマンドがある場合、コマンドクラスを単体テストして他のメンテナがコードを追加しないようにする方法がありますメンバーデータ(コンストラクタに渡された読み取り専用メンバー以外)?機能コマンドシステムのアーキテクチャを改善するのに役立つ必要がある

例: コードが開始されると、アクションにサービスを提供できるスクリプトアクションとコマンドの間のマッピングを作成します。

actionCommandTable = 
[“Translate”, new TranslateCommand(appcontext)], 
[“Scale”, new ScaleCommand(appcontext)], 
[“Assignment” new AssignmentCommand(appcontext, expressionEvaluator)] 

その後、実行時に:

actionCommandTable[“Translate”].Execute(actionDataContext); 

変換コマンド:

public class TranslateAction : ActionCommand { 
     //read-only interface 
     private readonly AliasProvider aliasMap; 
     //bad - need to prevent this instance from being added - will be overwritten unexpectedly 
     private int transientValue; 
     public TranslateAction(IAppContext appContext) { 
      aliasMap = appContext.AliasMap; 
     } 
     public override async Task Execute(ActionDataContext actionDataContext) { 
      //assign to transientValue 
      //do some work 
      //await an animation 
      //do more work 
      //read from transientValue 
     } 

    } 

この例では、Executeのすべての作業はoですkが共有メンバー上で動作しない場合はkです。

actionDataContextは、一時的なステートフルデータのターゲットとすることを意図しています。

+1

これは、あなたが単体テストよりもRoslynアナライザのほうがよいと思われます。 – svick

答えて

2

リフレクションを使用して、すべてのフィールドとプロパティが読み取り専用であることを確認できます。

- 割り当てが正しい場合は、検証のために、誰かがプロパティを宣言するときしかし、間違った方法を元にして初期化し、読み取り専用として、このシナリオをキャッチしませんあなたの条件

public void ValidateAllFieldsAreInitOnly(Type sut) 
    { 
     foreach(var field in sut.GetFields(BindingFlags.NonPublic | 
            BindingFlags.Instance | 
            BindingFlags.Static | 
            BindingFlags.Public)) 
     { 
      Assert.IsTrue(field.IsInitOnly); 
     } 

     foreach (var property in sut.GetProperties(BindingFlags.NonPublic | 
            BindingFlags.Instance | 
            BindingFlags.Static | 
            BindingFlags.Public)) 
     { 
      // returns true if the property has a set accessor, even if the accessor is private, internal 
      Assert.IsFalse(property.CanWrite); 

      // OR can use depending on requirement 

      // The MethodInfo object representing the Set method for this property if the set accessor is public, or null if the set accessor is not public. 
      Assert.IsNull(property.GetSetMethod()); 
     } 
    } 

ノートに基づいて指令値の割り当てを検証する必要があります

テスト

public class GoodCommand 
{ 

    private readonly string privateField1; 

    private readonly string privateField2; 
    public GoodCommand(string field1, string field2) 
    { 
     privateField1 = field1; 
     privateField2 = field2; 
    } 
} 

テスト用が緑色キャッチするであろう(赤)

public class BadCommand 
{ 

    private readonly string privateField1; 

    private string privateField2; 
    public BadCommand(string field1) 
    { 
     privateField1 = field1; 
     privateField2 = "testingbadCommand"; 
    } 
} 

このケースのテストは、要件に応じて適切な割り当てチェックが異なる場合があるため、緑色になります。割り当てられた値が期待どおりであるかどうかを確認することによっても、このシナリオを把握できます。

public class SmartBadCommand 
{ 
    private readonly string privateField1; 

    private readonly string privateField2; 
    public SmartBadCommand(string field1) 
    { 
     privateField1 = field1; 
     privateField2 = "testingbadCommand"; 
    } 
} 

このヘルプが必要です。

関連する問題