2009-07-22 17 views
1

現在、テスト容易性のためにWindows偽装を実行し、少しのロードブロッキングを実行したコードをリファクタリングしています。これは私がとのトラブルを抱えていたコードのビットです:単体テスト用のオブジェクトのインスタンス化を模擬する

... 
if (LogonUserA(user, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) > 0) 
{ 
    if (DuplicateToken(token, 2, ref tokenDuplicate)) 
    { 
     var tempWindowsIdentity = new System.Security.Principal.WindowsIdentity(tokenDuplicate); 
     var impersonationContext = tempWindowsIdentity.Impersonate(); 
     ... 
    } 
... 
} 

は、どのように私はWindowsIdentityオブジェクトをインスタンス化の動作を模擬しますか?私は、様々な選択肢を考えている:すなわちC++の関数ポインタのようなインスタンスを作成して、インスタンスの作成を処理する委譲でその

  • パスの動作を模擬うファクトリクラスで

    • 峠(私は、メソッドのシグネチャは次のようになりますよう、彼らは方法の意図をぼかししまう怖いので)これらの選択肢の

    どれも私には特に良いように見えるん:

    public bool Impersonate(string user, string password, string domain, Factory factory) 
    

    または

    public bool Impersonate(string user, string password, string domain, delegate WinIDCreator) 
    

    方法の目的は、特定のユーザーを偽装することであるので、ファクトリクラスまたは代理人のいずれかがそれに提供されるべきであることを私には意味がありません。しかし、私が単体テストを実行するたびに新しいWindowsIdentityインスタンスが作成されるという考えが不快なので、この動作を分離して模擬したいと思っています。

    アイデアやコメントはありますか?

  • 答えて

    4

    私はあなたがファクトリーのアイディアを持っていると思いますが、メソッドのパラメータではなく、クラスコンストラクタにファクトリを挿入します。デフォルトのコンストラクタは、デフォルトのFactoryが提供されていない場合、そのインスタンスを作成できます。

    また、LogonUserAとDuplicateTokenの方法も除外しないと、ユニットテストで実際のログインIDとパスワードが必要になるなど、いくつかの問題が発生します。私はあなたがコンストラクタにも注入することができるインターフェイスを実装するこの周りの薄いラッパーをお勧めします。

    以下は、構造化を開始する方法を示すハイライトの一部です。(オプションのよう工場を考える場合はプロパティを介して、おそらくまたは)

    public interface ILogonHelpers 
    { 
        bool LogonUser(string user, string domain, string password, ref int token); 
        void DuplicateToken( int token, ref int duplicateToken); 
    } 
    
    public class MyClass 
    { 
        public MyClass(ILogonHelper logonHelper, IIdentityFactory factory) 
        { 
         this.LogonHelper = logonHelper ?? new DefaultLogonHelper(); 
         this.IdentityFactory = factory ?? new DefaultIdentityFactory(); 
        } 
    
        ... 
    
    if (this.LogonHelper.Logon(user, domain, password, ref token) > 0) 
    { 
        if (this.LogonHelper.DuplicateToken(token, ref tokenDuplicate)) 
        { 
         var tempWindowsIdentity = this.IdentityFactory.CreateIdentity(tokenDuplicate); 
         var impersonationContext = tempWindowsIdentity.Impersonate(); 
         ... 
        } 
    ... 
    } 
    
    +0

    ありがとうございます。私は、NativeMethodsクラスにログオン項目をカプセル化し、単純にそれらを嘲笑していると付け加えておきます。クラスにファクトリをインジェクトする際の心配は、メソッドのパラメータとして使用することと同じです。クラスにクラスファクトリに依存することは自然ではありません。 – jpoh

    +0

    ieこのクラスは、それはNativeMethodsクラス(私が必要とするWin APIをカプセル化する)に依存しています。私はそれがFactoryクラスに対する依存性を持つこともOKであることを自分自身に確信させることは難しいと思っています。 – jpoh

    0

    私はあなたがモックできる仮想偽装メソッドを作成します。次のように偽装する方法は、次のようになります。

    
    public virtual WindowsImpersonationContext Impersonate(string tokenDuplicate) { 
        var tempWindowsIdentity = new System.Security.Principal.WindowsIdentity(tokenDuplicate); 
        var impersonationContext = tempWindowsIdentity.Impersonate(); 
    
        return impersonationContext; 
    } 
    
    1

    私は

    「ファクトリー」偽装メソッドを含むクラスの属性にしないのはなぜJavaのdevのだけど...?

    "factory"属性(おそらく "windowIdentityFactory")は、コンストラクタまたはセッタメソッド(ある種の依存関係注入を使用して)で設定できます。

    このテストでは、あなたが提案したように、モックファクトリをクラスに提供します。プロダクションでは、あなたはそれを真実にします。

    ... 
    if (LogonUserA(user, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) > 0) 
    { 
        if (DuplicateToken(token, 2, ref tokenDuplicate)) 
        { 
         var tempWindowsIdentity = windowIdentityFactory.newInstance(tokenDuplicate); 
         var impersonationContext = tempWindowsIdentity.Impersonate(); 
         ... 
        } 
    ... 
    } 
    
    0

    私は、コンストラクタを介して工場を注入についてtvanfossonに同意します。しかし、それについてあまり幸せではないので、私はあなたにちょっと変わった方法でインスタンスをモックさせるTypeMock Isolatorを見てみることをお勧めします。これは、プロファイラーと同様のILを注入することで機能し、オブジェクト設定を変更せずにモックを使用することができます。

    関連する問題