2010-08-17 3 views
1

J'utilise une aide dans mes contrôleurs et dans mes vues que j'ai trouvées quelque part sur Internet. L'assistant est appelé comme ceci dans mon contrôleur "Url.SiteRoot();" Comment puis-je faire en sorte que mon contrôleur ne lance pas d'exception à chaque appel de l'assistant? J'utilise MVCContrib et moq pour mes tests unitaires.MVC Mock HttpContextBase qui est utilisé dans un assistant

Je pense implémenter une sorte de vérification dans l'assistant, mais j'ai l'impression que le framework MVCContrib ou le moq devrait être capable de gérer cela, de sorte que je n'ai pas besoin d'ajouter du code d'exception dans mes helpers. capable de passer les tests unitaires.

Vous pouvez voir le code Helper ici: -

namespace System.Web.Mvc { 
public static class UrlHelpers { 

    public static string SiteRoot(HttpContextBase context) { 
     return SiteRoot(context, true); 
    } 

    public static string SiteRoot(HttpContextBase context, bool usePort) { 
     var Port = context.Request.ServerVariables["SERVER_PORT"]; 
     if (usePort) { 
      if (Port == null || Port == "80" || Port == "443") 
       Port = ""; 
      else 
       Port = ":" + Port; 
     } 
     var Protocol = context.Request.ServerVariables["SERVER_PORT_SECURE"]; 
     if (Protocol == null || Protocol == "0") 
      Protocol = "http://"; 
     else 
      Protocol = "https://"; 

     var appPath = context.Request.ApplicationPath; 
     if (appPath == "/") 
      appPath = ""; 

     var sOut = Protocol + context.Request.ServerVariables["SERVER_NAME"] + Port + appPath; 
     return sOut; 

    } 

    public static string SiteRoot(this UrlHelper url) { 
     return SiteRoot(url.RequestContext.HttpContext); 
    } 


    public static string SiteRoot(this ViewPage pg) { 
     return SiteRoot(pg.ViewContext.HttpContext); 
    } 

    public static string SiteRoot(this ViewUserControl pg) { 
     var vpage = pg.Page as ViewPage; 
     return SiteRoot(vpage.ViewContext.HttpContext); 
    } 

    public static string SiteRoot(this ViewMasterPage pg) { 
     return SiteRoot(pg.ViewContext.HttpContext); 
    } 

    public static string GetReturnUrl(HttpContextBase context) { 
     var returnUrl = ""; 

     if (context.Request.QueryString["ReturnUrl"] != null) { 
      returnUrl = context.Request.QueryString["ReturnUrl"]; 
     } 

     return returnUrl; 
    } 

    public static string GetReturnUrl(this UrlHelper helper) { 
     return GetReturnUrl(helper.RequestContext.HttpContext); 
    } 

    public static string GetReturnUrl(this ViewPage pg) { 
     return GetReturnUrl(pg.ViewContext.HttpContext); 
    } 

    public static string GetReturnUrl(this ViewMasterPage pg) { 
     return GetReturnUrl(pg.Page as ViewPage); 
    } 

    public static string GetReturnUrl(this ViewUserControl pg) { 
     return GetReturnUrl(pg.Page as ViewPage); 
    } 
} 
} 

Répondre

0

Vous avez sans doute réalisé que la raison pour laquelle vous obtenez des exceptions de vos méthodes d'extension est due aux propriétés inappliquées ou des méthodes sur les objets chinés, par exemple Demande sur HttpContextBase ou RequestContext sur UrlHelper. Jetez un oeil à certaines des stratégies affichées here pour des idées sur la façon de se moquer des appels de méthode d'extension. Personnellement, je préfère this strategy, ce qui vous obligerait à refactoriser vos méthodes d'extension pour parier swappable à l'exécution.

Par exemple, au lieu de:

public static class UrlHelperExtensions 
{ 
    public static string GetReturnUrl(this UrlHelper helper) 
    { 
     return // your implementation of GetReturnUrl here 
    } 

} 

Vous auriez:

public interface IUrlHelperExtensions 
{ 
    string GetReturnUrl(UrlHelper helper); 
} 

public static class UrlHelperExtensions 
{ 
    public static IUrlHelperExtensions Extensions(this UrlHelper target) 
    { 
     return UrlHelperExtensionFactory(target); 
    } 

    static UrlExtensions 
    { 
     UrlHelperExtensionFactory =() => new DefaultUrlHelperExtensionStrategy(); 
    } 

    public static Func UrlHelperExtensionFactory { get; set; } 
} 

public DefaultUrlHelperExtensionStrategy : IUrlHelperExtensions 
{ 
    public string GetReturnUrl(UrlHelper helper) 
    { 
     return // your implementation of GetReturnUrl here 
    } 
} 

Vous aurez besoin de changer la façon dont vous appelleriez vos méthodes d'extension, de urlHelper.GetReturnUrl () à urlHelper.Extensions(). GetReturnUrl(), et lors des tests unitaires, vous pouvez définir UrlHelperExtensions.UrlHelperExtensionFactory à un objet mocké, mais de cette façon, vous pouvez contrôler le comportement des méthodes d'extension au moment du test.

0

Ce code semble un peu compliqué. Je pense que cela fait la même chose et serait beaucoup plus facile à tester. (Je ne sais pas pourquoi il a besoin d'être bien.)

public string FullApplicationPath(HttpRequestBase request) 
{ 
    var path = request.Url.AbsoluteUri.Replace(request.Url.AbsolutePath,string.Empty); 
    if (!string.IsNullOrEmpty(request.Url.Query)) 
    { 
     path = path.Replace(request.Url.Query, string.Empty); 
    } 
    return path + request.ApplicationPath; 
} 
2

Comme Frey écrit @ Jeremy vous obtenez les exceptions parce que vous ne pas bouchonner/faux des parties essentielles du HttpContext.

Comment l'utilisation:

Request.Url.GetLeftPart(System.UriPartial.Authority) 

au lieu d'essayer de construire la logique pour la construction de l'URL vous-même? Si je me souviens bien, il devrait prendre correctement le protocole et le port, ainsi que tout répertoire virtuel, site, etc.

Questions connexes