2016-10-19 2 views
0

Ich habe eine Klasse in einer Klassenbibliothek, die von Windows-Anwendung oder Webanwendung verwendet werden soll.UnitTest zum Simulieren der Assembly, auf die von einer WebApplication verwiesen wird (mit IPrincipal-Füllung)

ist es definiert als

public class CredentialProviderPipelineStep 
{ 
    internal static string GetDomainFullName(string friendlyName) 
    { 
     var context = new DirectoryContext(DirectoryContextType.Domain, friendlyName); 
     var domain = Domain.GetDomain(context); 
     return domain?.Name; 
    } 


    public static Task<IDictionary<string, object>> Action(IConfiguration configuration) 
    { 

     return Task.Run<IDictionary<string, object>>(() => 
       { 
        var context = new Dictionary<string, object> 
        { 
         [Resources.DomainName] = GetDomainFullName(Environment.UserDomainName), 
         [Resources.DomainUser] = Environment.UserName 
        }; 

        if (configuration.AppSettings[Resources.SSOApplicationId] == null) 
         throw new KeyNotFoundException(Resources.SSOApplicationId); 

        context[Resources.ApplicationId] = 
         Convert.ToInt32(configuration.AppSettings[Resources.SSOApplicationId]); 

        return context; 
       }); 
    } 

    internal static IDictionary<string, object> GetUserAndDomain() 
    { 
     //It's to check if it's a web app, so I've to ask for principal data <see href="http://stackoverflow.com/questions/3179716/how-determine-if-application-is-web-application/"></see> 
     return Assembly.GetEntryAssembly() == null ? GetUserAndDomainFromWebApp() : GetUserAndDomainFromEnviorment(); 
    } 

    private static IDictionary<string,object> GetUserAndDomainFromEnviorment() 
    { 

     var httpContext = System.Web.HttpContext.Current.User.Identity.Name; 

     string[] splitted = httpContext.Split('\\'); 

     var result = new Dictionary<string, object> 
     { 
      [Resources.DomainName] = GetDomainFullName(Environment.UserDomainName), 
      [Resources.DomainUser] = Environment.UserName 
     }; 

     return result; 
    } 

    private static IDictionary<string, object> GetUserAndDomainFromWebApp() 
    { 
     var result = new Dictionary<string, object> 
     { 
      [Resources.DomainName] = GetDomainFullName(Environment.UserDomainName), 
      [Resources.DomainUser] = Environment.UserName 
     }; 

     return result; 
    } 

} 

Der kanonische Unittest (unter Verwendung von NUnit) deckt den GetUserAndDomainFromEnviorment Teil, aber wie kann ich einen Komponententest schreiben, die die Methode GetUserAndDomainFromWebApp abdecken? Also ist der System.Web.HttpContext.Current.User.Identity.Name gefüllt?

Dank

+0

Welche VS-Edition verwenden Sie? – nozzleman

Antwort

1

Ich schlage vor, die Abhängigkeit von System.Web.HttpContext in Ihrer Klasse Bibliothek zu entfernen. Dies kann durch eine einfache Schnittstelle erfolgen, die die Identität zurückgibt. Hier ist die Schnittstelle:

public interface IdentityProvider 
{ 
    System.Security.Principal.IIdentity GetIdentity(); 
} 

Nun, entfernen Sie das static Schlüsselwort auf die Methoden, die Sie Unit-Test möchten. Erstellen Sie einen Konstruktor für die CredentialProviderPipelineStep Klasse, die die Schnittstelle als Parameter übernimmt:

public CredentialProviderPipelineStep 
{ 
    IdentityProvider _identityProvider; 

    public CredentialProviderPipelineStep(IdentityProvider identityProvider) 
    { 
    _identityProvider = identityProvider; 
    } 
    ... 
} 

Dann eine Implementierung der Schnittstelle für das Web machen, die einfach die Identität in HttpContext gespeichert zurückgibt. Die andere Implementierung würde wahrscheinlich die Identität von System.Threading.Thread.CurrentPrincipal.Identity zurückgeben, die Informationen über den angemeldeten Benutzer in Windows enthält.

Sie können jetzt die -Methode entfernen, die versucht herauszufinden, ob Sie sich im Webkontext befinden oder nicht.

Es liegt nun an Ihrer Webanwendung oder Windows-Anwendung, die entsprechende Implementierung der Schnittstelle zu CredentialProviderPipelineStep zu liefern.

Diese Technik wird oft Dependency Inversion genannt, die das D in SOLID principles ist.

Hier ist eine gute Diskussion über Dependency Inversion: Inversion of Control from First Principles - Top Gear Style (und es ist auch ziemlich unterhaltsam).

Verwandte Themen